XH-a
XH-a

Reputation: 1

How to rotate a face(a series of coordinates)

def circle(point, radius):
    circle_vertices = []
    [x0, y0, z0] = point
    for angle in range(0, 360, 10):
        angle_radius = math.radians(angle)
        x = x0 + radius * math.cos(angle_radius)
        y = y0 + radius * math.sin(angle_radius)
        circle_vertices.append([x, y, z0])
    return circle_vertices

The following equation is to create two circles parallel to (x-y plane)

def cylinder(point_0, point_1, radius):
    circle_vertices_0 = circle(point=point_0, radius=radius)
    circle_vertices_1 = circle(point=point_1, radius=radius)

    cylinder_vertices = circle_vertices_1 + circle_vertices_0

    return cylinder_vertices

I would like to know how to rotate these two planes to generate two perpendicular to the p1-p0 direction enter image description here

Upvotes: 0

Views: 467

Answers (1)

won5830
won5830

Reputation: 592

Using directional vector point_1-point_0, and the unit vector along z-axis (k). You can get your 3 by 3 rotational matrix required for vector alignment between those two vectors (Calculate rotation matrix to align two vectors in 3D space).

import numpy as np 

def rotation_matrix_from_vectors(vec1, vec2):
    """ Find the rotation matrix that aligns vec1 to vec2
    :param vec1: A 3d "source" vector
    :param vec2: A 3d "destination" vector
    :return mat: A transform matrix (3x3) which when applied to vec1, aligns it with vec2.
    """
    a, b = (vec1 / np.linalg.norm(vec1)).reshape(3), (vec2 /np.linalg.norm(vec2)).reshape(3)
    v = np.cross(a, b)
    if any(v): #if not all zeros then 
        c = np.dot(a, b)
        s = np.linalg.norm(v)
        kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
        return np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2))
    else:
        return np.eye(3) #cross of all zeros only occurs on identical directions

Here is your new sample code.

def circle(radius):
    circle_vertices = []
    for angle in range(0, 360, 10):
        angle_radius = math.radians(angle)
        x = radius * math.cos(angle_radius)
        y = radius * math.sin(angle_radius)
        circle_vertices.append([x, y, 0])
    return circle_vertices

def cylinder(point_0, point_1, radius):
    rot = rotation_matrix_from_vectors(np.array([0,0,1]), point_0 - point_1)
    base_circle = np.array(circle(radius=radius))
    circle_vertices_0 = np.transpose([email protected](circle(radius=radius)).T) + point_0
    circle_vertices_1 = np.transpose([email protected](circle(radius=radius)).T) + point_1
    cylinder_vertices = np.concatenate((circle_vertices_0, circle_vertices_1), axis = 0)

    return cylinder_vertices

Taking example of point_0 = np.array([2,0,3]) and point_1 = np.array([4,0,8]), cylinder(point_0, point_1, radius = 3) gives you the result as below. temp

Upvotes: 1

Related Questions