简体   繁体   中英

How can I define a custom class of vector points in 3d space and calculate their center(mean) point?

I'm making a program that makes shapes and such. I want to find the center of a face (provided by a list of 3d vector points) by finding the average of each vector point that exist on it. Here is what I have tried:

import math

class vector:

    def __init__(self, x, y, z):

        self.x = x
        self.y = y
        self.z = z

class plane:

    def __init__(self, pointsList):

        self.vertex = []

        # check that each point is unique
        for p in range(0, len(pointsList)-1):


            for i in range(p+1, len(pointsList)):

                if (pointsList[p] != pointsList[i]):
                        if (i == len(pointsList)-1):
                            self.vertex.append(pointsList[p])

                else:
                    return None
        self.vertex.append(pointsList[-1])


    #returns the mean of x, y, and z            
    def center(self):

        xs = 0
        ys = 0
        zs = 0
        count = len(self.vertex)    

        for i in range(0, count):
            xs += self.vertex[i].x

            ys += self.vertex[i].y

            zs += self.vertex[i].z

        xMean = xs/count
        yMean = ys/count
        zMean = zs/count


        return vector(xMean, yMean, zMean)

and then I go to test the function plane.center():

#initialize some vectors
A = vector(1,7,5)
B = vector(3,9,4)
C = vector(0,1,0)
D = vector(0,0,0)

testList = [A, B, C, D]

#initialize a plane with those vectors
plane1 = plane(testList)

acenter = plane1.center()
print('%d %d %d' % (acenter.x, acenter.y, acenter.z))

then the result returned is 1 4 2. I wanted the mean of the x components, y components, and z components, but 4 is clearly not the average of 7, 9, 1, and 0 . The expected outcome should be 1.0, 4.25, 2.25 . How can I achieve that?

Thanks all. yeah I see the error now. it was something really simple, and I feel silly. I was thinking it had something to do with my interpreter defaulting to python 2, but that was obviously way off.

Even though you've solved your problem on your own, I'll give my two cents here. You can use Python's built-in dataclass to construct the vector . This will make sure that you don't have to make handmade rules to check if all the vectors in the lists are unique. You can directly use set function to make sure that there are no duplicate vectors (I have refactored the variable names to comply with PEP8)

import math
from dataclasses import dataclass
from typing import Union

# using dataclass to build the vector class
# unsafe_hash = True makes the class hashable
@dataclass(unsafe_hash=True)
class Vector:
    x: Union[int, float]
    y: Union[int, float]
    z: Union[int, float]

Now let's build the Plane class:

class Plane:
    def __init__(self, points_list):

        self.vertex = []
        self.points_list = points_list

    def _check_unique(self):
        """Check and make sure that there are no duplicate points in the list."""
        self.vertex = list(set(self.points_list))

        return self.vertex

    # returns the mean of x, y, and z
    def center(self):

        xs = 0
        ys = 0
        zs = 0

        vertex = self._check_unique()
        count = len(vertex)

        for i in range(0, count):
            xs += vertex[i].x

            ys += vertex[i].y

            zs += vertex[i].z

        x_mean = xs / count
        y_mean = ys / count
        z_mean = zs / count

        return Vector(x_mean, y_mean, z_mean)

Now let's see them in action:

# initialize some vectors
A = vector(1, 7, 5)
B = vector(3, 9, 4)
C = vector(0, 1, 0)
D = vector(0, 0, 0)

testList = [A, B, C, D, A, B]

# initialize a plane with those vectors
plane1 = plane(testList)

acenter = plane1.center()
print(f"{acenter.x}, {acenter.y}, {acenter.z}")

This will give you:

1.0, 4.25, 2.25

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM