Пример #1
0
    def first_blip(self, squash_axis, origin, initial_direction):
        '''
        Flatten the mesh to the plane, dropping the dimension identified by
        `squash_axis`: 0 for x, 1 for y, 2 for z. Cast a ray from `origin`,
        pointing along `initial_direction`. Sweep the ray, like a radar, until
        encountering the mesh, and return that vertex: like the first blip of
        the radar. The radar works as if on a point cloud: it sees sees only
        vertices, not edges.

        The ray sweeps clockwise and counterclockwise at the same time, and
        returns the first point it hits.

        If no intersection occurs within 90 degrees, return None.

        `initial_direction` need not be normalized.

        '''
        from blmath.numerics import as_numeric_array

        origin = vx.reject_axis(as_numeric_array(origin, (3, )),
                                axis=squash_axis,
                                squash=True)
        initial_direction = vx.reject_axis(as_numeric_array(
            initial_direction, (3, )),
                                           axis=squash_axis,
                                           squash=True)
        vertices = vx.reject_axis(self.v, axis=squash_axis, squash=True)

        origin_to_mesh = vx.normalize(vertices - origin)
        cosines = vx.normalize(initial_direction).dot(origin_to_mesh.T).T
        index_of_first_blip = np.argmax(cosines)

        return self.v[index_of_first_blip]
Пример #2
0
    def from_points_and_vector(cls, p1, p2, vector):
        '''
        Compute a plane which contains two given points and the given
        vector. Its reference point will be p1.

        For example, to find the vertical plane that passes through
        two landmarks:

            from_points_and_normal(p1, p2, vector)

        Another way to think about this: identify the plane to which
        your result plane should be perpendicular, and specify vector
        as its normal vector.

        '''
        from blmath.numerics import as_numeric_array

        p1 = as_numeric_array(p1, shape=(3, ))
        p2 = as_numeric_array(p2, shape=(3, ))

        v1 = p2 - p1
        v2 = as_numeric_array(vector, shape=(3, ))
        normal = np.cross(v1, v2)

        return cls(point_on_plane=p1, unit_normal=normal)
Пример #3
0
    def __init__(self, origin, shape):
        '''
        origin: The x, y, z coordinate of the origin.
        shape: A sequence containing the width (dx), height (dy), and
          depth (dz).

        '''
        from blmath.numerics import as_numeric_array
        self.origin = as_numeric_array(origin, shape=(3,))
        self.shape = as_numeric_array(shape, shape=(3,))
        if any(np.less(self.shape, 0)):
            raise ValueError('Shape should be zero or positive')
Пример #4
0
    def from_points(cls, p1, p2, p3):
        '''
        If the points are oriented in a counterclockwise direction, the plane's
        normal extends towards you.

        '''
        from blmath.numerics import as_numeric_array

        p1 = as_numeric_array(p1, shape=(3, ))
        p2 = as_numeric_array(p2, shape=(3, ))
        p3 = as_numeric_array(p3, shape=(3, ))

        v1 = p2 - p1
        v2 = p3 - p1
        normal = np.cross(v1, v2)

        return cls(point_on_plane=p1, unit_normal=normal)
Пример #5
0
    def v(self, val):  # setter_property incorrectly triggers method-hidden. pylint: disable=method-hidden
        '''
        Update the vertices to a new array-like thing containing points
        in 3D space. Set to None for an empty polyline.

        '''
        from blmath.numerics import as_numeric_array
        self.__dict__['v'] = as_numeric_array(val, dtype=np.float64, shape=(-1, 3), allow_none=True)
        self._update_edges()
Пример #6
0
 def v(self, val):
     # cached properties that are dependent on v
     self._clear_cached_properties('vertices_to_edges_matrix',
                                   'vertices_to_edges_matrix_single_axis')
     self.__dict__['v'] = as_numeric_array(val,
                                           dtype=np.float64,
                                           shape=(-1, 3),
                                           allow_none=True,
                                           empty_as_none=True)
Пример #7
0
    def reorient(self, up, look):
        '''
        Reorient the mesh by specifying two vectors.

        up: The foot-to-head direction.
        look: The direction the body is facing.

        In the result, the up will end up along +y, and look along +z
        (i.e. facing towards a default OpenGL camera).

        '''
        from blmath.geometry.transform import rotation_from_up_and_look
        from blmath.numerics import as_numeric_array

        up = as_numeric_array(up, (3, ))
        look = as_numeric_array(look, (3, ))

        if self.v is not None:
            self.v = np.dot(rotation_from_up_and_look(up, look), self.v.T).T
Пример #8
0
 def fn(self, val):
     '''
     Note that in some applications, face normals are vectors, in others they are indexes into the vertex normal array.
     Someday we should refactor things so that we have seperate fn (face normal vectors) & fvn (face vertex normal indicies).
     Today is not that day.
     '''
     self.__dict__['fn'] = as_numeric_array(val,
                                            dtype=np.float64,
                                            shape=(-1, 3),
                                            allow_none=True,
                                            empty_as_none=True)
Пример #9
0
 def e(self, val):
     self.__dict__['e'] = as_numeric_array(val,
                                           dtype=np.uint64,
                                           shape=(-1, 2),
                                           allow_none=True,
                                           empty_as_none=True)
Пример #10
0
 def vt(self, val):
     self.__dict__['vt'] = as_numeric_array(val,
                                            dtype=np.float64,
                                            shape=(-1, 2),
                                            allow_none=True,
                                            empty_as_none=True)
Пример #11
0
 def ft(self, val):
     self.__dict__['ft'] = as_numeric_array(val,
                                            dtype=np.uint32,
                                            shape=(-1, 3),
                                            allow_none=True,
                                            empty_as_none=True)