pythonのカスタムベクトル計算ベクトル積、平行四角形面積、三角形面積

3393 ワード

# coding=utf-8
from math import sqrt, acos, pi


class Vector(object):
    """docstring for Vector"""
    """              ,              """
    CANNOT_NORMALIZE_ZERO_VECTOR_MSG = 'Cannot normalize the zero vector'
    NO_UNIQUE_ORTHOGONAL_COMPONENT_MSG = "No_unique_orthogonal_component_msg"
    def __init__(self, coordinates):
        super(Vector, self).__init__()
        try:
            if not coordinates:
                raise ValueError
            self.coordinates = tuple(coordinates)
            self.dimension = len(coordinates)    
        except ValueError:
            raise ValueError('The coordinates must be nonempty')
        except TypeError:
            raise TypeError('The coordinates must be an iterable')



    def __str__(self):
        return 'Vector: {}'.format(self.coordinates)


    #       
    def magnitude(self):
        coordinates_squared = [x**2 for x in self.coordinates]
        return sqrt(sum(coordinates_squared))


    #     
    def crossProduct(self,w):
        new_cordinates = []
        new_cordinates.append(self.coordinates[1]*w.coordinates[2]- w.coordinates[1]*self.coordinates[2])
        new_cordinates.append(-(self.coordinates[0]*w.coordinates[2] - w.coordinates[0]* self.coordinates[2]))
        new_cordinates.append(self.coordinates[0]*w.coordinates[1] - w.coordinates[0]*self.coordinates[1])
        return Vector(new_cordinates)

   #        
    def areaOfParallelogram(self,w):
        vector_product = self.crossProduct(w)
        return vector_product.magnitude()

   #      
    def areaOfTriangle(self,v):
        return self.areaOfParallelogram(v)/2


v1 = Vector([8.462, 7.893,-8.187])
v2 = Vector([6.984, -5.975,4.778])
print v1.crossProduct(v2)

v3 = Vector([-8.987, -9.838, 5.031])
v4 = Vector([-4.268, -1.861, -8.866])
print v3.areaOfParallelogram(v4)


v5 = Vector([1.5,9.547,3.691])
v6 = Vector([-6.007,0.124,5.772,])
print v5.areaOfTriangle(v6)

# Vector: (-11.204570999999994, -97.609444, -105.68516199999999)
# 142.122221402
# 42.5649373994
# [Finished in 0.1s]



最適化後
   #      
    def areaOfTriangle(self,v):
        return self.areaOfParallelogram(v)/2

    def cross(self,v):
        try:
            x_1,y_1,z_1 = self.coordinates
            x_2,y_2,z_2 = v.coordinates
            new_cordinates = [  y_1*z_2 - y_2*z_1,
                              -(x_1*z_2 - x_2*z_1),
                                x_1*y_2 - x_2*y_1]
            return Vector(new_cordinates)

        except Exception, e:
            msg = str(e)
            if msg == 'need more than 2 values to unpack':
                self_embedded_in_R3 = Vector(self.coordinates + ('0',))
                v_embedded_in_R3 = Vector(v.coordinates + ('0',))
                return self_embedded_in_R3.cross(v_embedded_in_R3)
            elif (msg == 'too many values to unpack' or msg == 'need more than 1 value to unpack'):
                raise Exception(self.ONLY_DEFINZED_IN_TWO_THREE_DIMS_MSG)
            else:
                raise e

   
    def area_of_parallelogram_with(self,v):
        cross_product = self.cross(v)
        return cross_product.magnitude()

    def area_of_triangle_with(self, v):
        return self.area_of_parallelogram_with(v)/2