Beispiel #1
0
    def __init__(self, bandgap=555, origin=(0, 0, 0), size=(1, 1, 1), shape="box"):
        super(Channel, self).__init__()
        self.origin = np.array(origin)
        self.size = np.array(size)
        self.volume = 1
        if shape == "box":
            self.shape = Box(origin=origin, extent=np.array(origin) + np.array(size))
            for coord in size:
                self.volume *= coord
        elif shape == "cylinder":  # takes radius, length
            # The following is a little workaround to convert origin, size into cylinder (radius, length) descriptors
            # Axis is based on the longest direction among the size (x,y,z)
            axis = np.argmax(size)
            # Length is the value of the longest axis of size
            length = np.amax(size)
            # Radius is the average of the other two coordinates divided by two (radius, not diameter!)
            radius = np.average(np.delete(size, axis)) / 2  # Div. by 2 cause what's given it's the diameter

            # Cylinder volume formula
            self.volume = math.pi * radius ** 2 * length

            self.shape = Cylinder(radius=radius, length=length)

            # For CSG first rotation then translation (assuming scaling is not needed)
            if axis == 0:  # Z to X Rotation needed
                self.shape.append_transform(tf.rotation_matrix(math.pi / 2.0, [0, 1, 0]))
            elif axis == 1:  # Z to Y Rotation needed
                self.shape.append_transform(tf.rotation_matrix(-math.pi / 2.0, [1, 0, 0]))

            self.shape.append_transform(tf.translation_matrix(origin))
        else:
            self.logger.warn("The channel shape is invalid (neither box nor cylinder. It was " + str(shape))
            raise Exception("Channel has invalid shape")
        self.material = SimpleMaterial(bandgap)
        self.name = "Channel"
Beispiel #2
0
 def __init__(self, bandgap=555, base=1, alpha=np.pi / 3, beta=np.pi / 3, length=1):
     super(Prism, self).__init__()
     h = base * (1 / np.tan(alpha) + 1 / np.tan(alpha))
     box0 = Box(origin=(0, 0, 0), extent=(base, h, length))
     box1 = Box(origin=(0, 0, 0), extent=(h / np.sin(alpha), h, length))
     box1.append_transform(tf.rotation_matrix(alpha, (0, 0, 1)))
     box2 = Box(origin=(base, 0, 0), extent=(base + h, h / np.sin(beta), h, length))
     box2.append_transform(tf.rotation_matrix(np.pi / 2 - beta, (0, 0, 1)))
     step1 = CSGsub(box0, box1)
     step2 = CSGsub(step1, box2)
     self.shape = step2
     self.material = SimpleMaterial(bandgap)
def transform_direction(direction, transform):
    angle, axis, point = tf.rotation_from_matrix(transform)
    rotation_transform = tf.rotation_matrix(angle, axis)
    return np.array(
        np.dot(rotation_transform,
               np.matrix(np.concatenate(
                   (direction,
                    [1.]))).transpose()).transpose()[0, 0:3]).squeeze()
Beispiel #4
0
def transform_direction(direction, transform):
    try:
        rotation_angle, rotation_axis, point = tf.rotation_from_matrix(transform)
    except ValueError:
        if tf.is_same_transform(tf.identity_matrix() * -1, transform):
            # The ray direction needs to be reversed
            return np.array(direction) * -1.
    rotation_transform = tf.rotation_matrix(rotation_angle, rotation_axis)
    return np.array(np.dot(rotation_transform,
                           np.matrix(np.concatenate((direction, [1.]))).transpose()).transpose()[0,0:3]).squeeze()
Beispiel #5
0
def rotation_matrix_from_vector_alignment(before, after):
    """
    :param before: vector before rotation
    :param after: vector after rotation
    :return: rotation matrix
    """
    """
    >>> # General input/output test
    >>> V1 = norm(np.random.random(3))
    >>> V2 = norm([1, 1, 1])
    >>> R = rotation_matrix_from_vector_alignment(V1, V2)
    >>> V3 = transform_direction(V1, R)
    >>> cmp_points(V2, V3)
    True
    >>> # Catch the special case in which we cannot take the cross product
    >>> V1 = [0, 0, 1]
    >>> V2 = [0, 0, 1]
    >>> R = rotation_matrix_from_vector_alignment(V1, V2)
    >>> V3 = transform_direction(V1, R)
    >>> cmp_points(V2, V3)
    True
    >>> # Catch the special case in which we cannot take the cross product
    >>> V1 = [0, 0, 1]
    >>> V2 = [0, 0, -1]
    >>> R = rotation_matrix_from_vector_alignment(V1, V2)
    >>> V3 = transform_direction(V1, R)
    >>> cmp_points(V2, V3)
    True
    """
    # The angle between the vectors must not be 0 or 180 (i.e. so we can take a cross product)
    # import pdb; pdb.set_trace()
    the_dot = np.dot(before, after)
    if cmp_floats(the_dot, 1.):
        # Vectors are parallel
        return tf.identity_matrix()

    if cmp_floats(the_dot, -1.):
        # Vectors are anti-parallel
        # print "Vectors are anti-parallel this might crash."
        return tf.identity_matrix() * -1.

    rotation_axis = np.cross(before, after)  # get the axis of rotation
    rotation_angle = np.arccos(np.dot(before, after))  # get the rotation angle
    return rotation_matrix(rotation_angle, rotation_axis)
Beispiel #6
0
 def rotate(self, angle, axis):
     self.shape.append_transform(tf.rotation_matrix(angle, axis))
Beispiel #7
0
 def rotate(self, angle, axis):
     self.shape.append_transform(tf.rotation_matrix(angle, axis))
def transform_direction(direction, transform):
    angle, axis, point = tf.rotation_from_matrix(transform)
    rotation_transform = tf.rotation_matrix(angle, axis)
    return np.array(np.dot(rotation_transform,
                           np.matrix(np.concatenate((direction, [1.]))).transpose()).transpose()[0, 0:3]).squeeze()