2012-07-20 119 views
1

我想創建一個函數,知道一條線是否碰到一個點。有沒有這樣的功能?我也想設置釐米的3D點的大小,並不知道如何做到這一點。3D線點擊3D點?

我感謝您的幫助。

例如: enter image description here

假設點有一個半徑和線難道不中間準確擊中點,是顯示我,如果一條線命中點的功能?

+0

哦,那是艱難的(一般)。我也很想知道! – 2012-07-20 09:49:35

+0

你的線條和球體是如何表現的?你爲什麼使用'matplotlib'標籤? – jfs 2012-07-20 10:13:00

+0

當然,如果您知道線的方程(a * x + b * y + c * z = 0),您可以用a,b和c(點的座標)的值替換,然後檢查-d jaypeagi 2012-07-20 16:54:31

回答

3

我想到你居然要計算什麼是3D

看到的點和線間的距離:Point-Line Distance

當距離大於在你點球體的半徑小,你有一場比賽。

+0

謝謝你。但是我怎樣才能將我的積分尺寸設置爲0.3釐米? – 2012-07-20 11:17:53

+0

,這取決於您用於剩餘計算的單位。你只需要以釐米爲單位指定3d線和點。那麼你可以檢查結果距離d是否小於0.3釐米。 – Dirk 2012-07-20 11:25:06

2

好吧,我有經典的解決方案,在任何維度工作。

首先,你得到了球體和一條線,你需要有一個好的模型。 球體很容易,你只需要一個矢量.center.diameter

class Sphere: 
    def __init__(sphere, center, diameter): 
     sphere.center=Vector(center) 
     sphere.diameter=float(diameter) 

對於初學者來說,線路可能會有更多問題,因爲它可能以多種方式定義。 最有用的來自參數方程式,您在矢量.direction和某個起始點.center中有一個方向。我們假設.direction是單位長度,.center是從(0,0)開始的最接近的點。在大多數情況下,我們需要創建一個行,不必分向量:

def line_on_two_points(A, B): 
    return Line(direction= Vector(B)-A, center=A) 

所以我們必須解決在構造函數中directioncenter.direction很容易修復,只需要使其長度單位。要找到.center,我們需要scalar projection。這裏是矢量d: The nearest point on line from (0,0)

.direction爲單位長度A到B和center從C到A,我們可以初始化我們的路線爲:

class Line: 
    def __init__(line, direction, center): 
     line.direction= Vector(direction)/length(direction) 
     line.center= center - line.direction*dot(center,line.direction) 

如果我們沒有一個行,我們可能只是做到這兩點:

#class Sphere: 
def colide_line_on_two_points(sphere, A, B): 
    line=line_on_two_points(A-sphere.center, B-sphere.center) 
    return length(line.center) < sphere.diameter 

但是,當我們有一個行,我們嘗試將其作爲優化:

#class Sphere: 
def colide_line(sphere, line): 
    return line.distance_to(sphere.center) < sphere.diameter 

.distance_to()功能是有點棘手:

Vector from line to point

#class Line: 

    def vector_to(line, P): 
     return line.center + line.direction * dot(line.direction,P) - P 

    def distance_to(line, P): 
     return length(line.center + line.direction * dot(line.direction,P) - P) 

    def move_to(line, P): 
     line.center += line.direction * dot(line.direction,P) - P 

最後但並非最不重要的是Vector類型,我嘗試numpy的,但它是相當緩慢的2D,3D:

from numpy import array as Vector 
from numpy import dot 
from numpy.linalg import norm as length 
0

你正在尋找的是一種算法來找到線條和球體之間的交集。這是圖形編程中常見的問題,並且有很多文章可能會比我更好地解釋它。有一個在http://www.lighthouse3d.com/tutorials/maths/ray-sphere-intersection/

其基本思想是將球投影到線上,然後使用畢達哥拉斯定理求解由交點,球的中心和投影點組成的直角三角形。 。

這是我在pathtracing渲染器使用的代碼:

hitdata intersectwith(Sphere sphere) 
{ 
    d3Vector projected; 

    float t = V.dot(sphere.pos.subtract(O)); 
    projected = V.normalize().scalarmultiply(t); //the projected vector 
    float distnce = (projected.subtract(sphere.pos.subtract(O))).magnitude(); 
    //the length between the center of your sphere and the projected point 
    hitdata outdata; // a class containing the results of the intersection 
    outdata.hit = false; 
    outdata.t = 110; 
    if(t<=0) 
    { 
     return outdata; 
    } 
    if(distnce<sphere.r) 
    {// the line is less distant from the center of the sphere than the surface 
     outdata.hit = true; 
     float deltaT = sqrtf((sphere.r*sphere.r)-(distnce*distnce));//Pythagorean theorem 
     outdata.coord = O.add(V.scalarmultiply(t-deltaT)); 
     //calculating intersection coordinates 
     outdata.normal = outdata.coord.subtract(sphere.pos); 
     outdata.normal = outdata.normal.normalize();//calculating surface normals 
     outdata.material = sphere.material; 
     outdata.t = t-deltaT; 
    } 
    return outdata; 
} 
+0

請添加鏈接 – Lizz 2015-01-06 15:21:52

+1

的相關代碼和描述我添加了我自己的路徑跟蹤代碼 – 2015-01-23 01:48:39