1. 程式人生 > 實用技巧 >3維直線和麵的交點計算

3維直線和麵的交點計算

簡介

3為之間和麵交點的計算,其實百度百科上講的比較清楚了

link

百度百科 連結 https://baike.baidu.com/item/線面交點/23119069?fr=aladdin
講的真的很好

python code

# coding=utf-8
from scipy.optimize import fsolve #匯入求解方程組的函式 非線性方程組
import numpy as np
from scipy import linalg
class Point2D:
    # AX+BY+C = 0
    # 二維的一般式方程
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Line2D:
    # AX+BY+C = 0
#   # 二維的一般式方程
    def __init__(self, A, B, C):
        self.A = A
        self.B = B
        self.C = C
    def init_from_two_point2d(self, a, b):
        self.A = b.y - a.y
        self.B = a.x - b.x
        self.C = b.x * a.y - a.x * b.y
    def getABC(self):
        return self.A, self.B, self.C


class Point3D:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

class Vec3D:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

class Face3D:
    # 一般表示形式
    def __init__(self):
        self.points = []
        self.n = [0,0,0]
    def init_from_three_point3d(self, a, b, c):
        # https://zhidao.baidu.com/question/456206521205069445.html
        # 首先求出平面的法向量 Point3D 型別
        vec1 = [a.x - b.x, a.y - b.y, a.z - b.z]
        vec2 = [a.x - c.x, a.y - c.y, a.z - c.z]
        self.n = Vec3D(vec1[1]*vec2[2] - vec2[1]*vec1[2],
                vec2[0]*vec1[0] - vec1[0]*vec2[2],
                vec1[0]*vec2[1] - vec2[0]*vec1[1])
        self.points.append(a)
        self.points.append(b)
        self.points.append(c)

        # https://baike.baidu.com/item/%E7%BA%BF%E9%9D%A2%E4%BA%A4%E7%82%B9/23119069?fr=aladdin
        # (p - p_0)*n = 0

class Line3D:
    def __init__(self):
        self.l = [0, 0, 0]
        self.points = []
    def init_from_two_point3d(self, a, b):
        # p = d * l + l_0
        self.l = Vec3D(a.x - b.x, a.y - b.y, a.z - b.z)
        self.points.append(a)
        self.points.append(b)


def intersection_line3D_Face3D(line, face):
    # https://baike.baidu.com/item/%E7%BA%BF%E9%9D%A2%E4%BA%A4%E7%82%B9/23119069?fr=aladdin
    l = line.l
    n = face.n
    if l.x * n.x + l.y * n.y + l.z * n.z == 0:
        print("[DEBUG] 平行 暫時不考慮重合")
        return

    d = ((face.points[0].x - line.points[0].x) * n.x + (face.points[0].y - line.points[0].y) * n.y
        + (face.points[0].z - line.points[0].z) * n.z) / (l.x * n.x + l.y * n.y + l.z * n.z)
    print("[DEBUG] intersection point[x, y, z] ", [d * line.l.x + line.points[0].x, d * line.l.y + line.points[0].y
                                          , d * line.l.z + line.points[0].z])




def intersection_line2D_line2D(line1, line2):
    A,B,C = line1.getABC()
    D,E,F = line2.getABC()
    # 判斷這兩條直線是否是重合的 或者平行的
    w = np.array([[A, B, C], [D, E, F]])
    if(np.linalg.matrix_rank(w) != 2):
        print('[ERROR] coincide  重合')
        return
    ww = np.array([[A, B], [D, E]])
    if(np.linalg.matrix_rank(ww) == 1 and C != F):
        print('[ERROR] parallel 平行')
        return
    AA = np.array([[A, B], [D, E]])
    BB = np.array([-C, -F])
    x = linalg.solve(AA, BB)
    print("[DEBUG] intersection on the point[x,y]", x)

if __name__ == "__main__":
    l0 = Point3D(0,0,0)
    l1 = Point3D(1,1,1)
    l = Line3D()
    l.init_from_two_point3d(l0, l1)
    f0 = Point3D(0,0,0)
    f1 = Point3D(1,1,0)
    f2 = Point3D(2,3,0)
    f = Face3D()
    f.init_from_three_point3d(f0, f1, f2)
    intersection_line3D_Face3D(l, f)