Circle in 3D space

发布于 2022-10-13  359 次阅读


Please refresh the page if equations are not rendered correctly.
---------------------------------------------------------------

通过指定圆心,圆所在平面的法线,半径来绘制三维空间中的圆。

直接找出圆所在的平面

找出圆所在的平面并在该平面上定义圆

import numpy as np

def three_dimensional_circle(centroid, normal, radius, num_points=50):
    """
    Generate points along the circumference of a three-dimensional circle.

    Parameters:
    - centroid (list): Coordinates of the circle's centroid.
    - normal (list): Normal vector of the circle's plane.
    - radius (float): Radius of the circle.
    - num_points (int, optional): Number of points on the circle. Default is 50.

    Returns:
    - np.ndarray: Array containing points on the circle.
    """
    theta = np.linspace(0, 2 * np.pi, num_points)

    # Define coordinate axes in the circle's plane
    v3 = normal
    v1 = np.array([v3[2], 0, -v3[0]]) / np.linalg.norm([v3[2], 0, -v3[0]])
    v2 = np.cross(v3, v1)

    # Extract centroid coordinates
    cx, cy, cz = centroid[0], centroid[1], centroid[2]

    # Calculate points on the circle
    ray_end = np.zeros([len(theta), 3])
    ray_end[:, 0] = cx + radius * (v1[0] * np.cos(theta) + v2[0] * np.sin(theta))
    ray_end[:, 1] = cy + radius * (v1[1] * np.cos(theta) + v2[1] * np.sin(theta))
    ray_end[:, 2] = cz + radius * (v1[2] * np.cos(theta) + v2[2] * np.sin(theta))

    return ray_end

先定义圆在旋转到所需平面

import numpy as np

import numpy as np

def three_dimensional_circle(centroid, normal, radius, num_points=50):
    """
    Generate points along the circumference of a three-dimensional circle.

    Parameters:
    - centroid (list): Coordinates of the circle's centroid.
    - normal (list): Normal vector of the circle's plane.
    - radius (float): Radius of the circle.
    - num_points (int, optional): Number of points on the circle. Default is 50.

    Returns:
    - np.ndarray: Array containing points on the circle.
    """
    theta = np.linspace(0, 2 * np.pi, num_points)

    x1 = radius * np.cos(theta)
    y1 = radius * np.sin(theta)
    z1 = np.zeros(theta.shape[0])

    A1 = np.arcsin(-normal[1] / np.sqrt(normal[1]**2 + normal[2]**2))
    B1 = np.arcsin(normal[0] / np.sqrt(normal[0]**2 + normal[2]**2))
    C1 = 0

    Rx_A1 = np.array([[1, 0, 0], [0, np.cos(A1), np.sin(A1)], [0, -np.sin(A1), np.cos(A1)]])
    Ry_B1 = np.array([[np.cos(B1), 0, -np.sin(B1)], [0, 1, 0], [np.sin(B1), 0, np.cos(B1)]])
    Rz_C1 = np.array([[np.cos(C1), np.sin(C1), 0], [-np.sin(C1), np.cos(C1), 0], [0., 0., 1.]])

    Rxyz1 = np.linalg.multi_dot((Rz_C1, Ry_B1, Rx_A1, np.array([x1, y1, z1])))

    ray_end = np.zeros([len(theta), 3])
    XC, YC, ZC = centroid[0], centroid[1], centroid[2]
    ray_end[:, 0] = Rxyz1[0, :] + XC * np.ones(len(theta))
    ray_end[:, 1] = Rxyz1[1, :] + YC * np.ones(len(theta))
    ray_end[:, 2] = Rxyz1[2, :] + ZC * np.ones(len(theta))

    return ray_end


normal = [1,1,1]
centroid = [1,1,1]
radius = 2

rayEnd = threeDimensionalCircle(centroid, normal, radius, numPoints = 50)

使用描述圆的节点作为Ray求与三角形网格的交点

以下代码不完整,仅示意用法。

import numpy as np
import trimesh

plane_origin = centerline[iSlice]
plane_normal = tangent_ubinder[iSlice]

# Create some rays
radius, numPoints = 1, 80
ray_origins = np.zeros([numPoints, 3])
ray_origins[:] = plane_origin
rayEnd = threeDimensionalCircle(plane_origin, plane_normal, radius, numPoints)

ray_directions = rayEnd - plane_origin

# Get the intersections
locations, index_ray, index_tri = mesh.ray.intersects_location(
    ray_origins=ray_origins, ray_directions=ray_directions)

trimesh函数解释:

Signature: mesh.ray.intersects_location(ray_origins,
                                        ray_directions,
                                        multiple_hits=True)
    Docstring:


Return the location of where a ray hits a surface.

Parameters
----------
ray_origins:    (n,3) float, origins of rays
ray_directions: (n,3) float, direction (vector) of rays


Returns
---------
locations: (n) sequence of (m,3) intersection points
index_ray: (n,) int, list of ray index
index_tri: (n,) int, list of triangle (face) indexes

Everything not saved will be lost.
最后更新于 2023-12-04