射線與球的相交性檢測

2021-07-14 21:01:58 字數 3653 閱讀 5546

射線和圓相交, origin是射線起點, dir是射線的方向向量。p0,p1是兩個交點,center為圓心,半徑為r,d為圓心到射線的距離。

我們先以2d切面圖來說明,當射線和圓相交的時候,可以看到,球心 center 到射線 ray 的距離 d <= r,這個即為相交的條件。那麼射線與球相切就轉化為了球心到射線的距離d的判斷。先求出d:

設圓心在射線上的投影為c',則 origin,center, c' 形成了乙個直角三角形。

獲得射線起點到圓心的向量voc = vcenter - vorigin

在射線方向上的投影為:poc = voc·dir

勾股定理:d·d = voc·voc - poc·poc

可以求出d的數值,

接下來求p0,p1:

c',center,p0 or p1點構成直角三角形。

p0 or p1到c'的距離 tca·tca = r·r - d·d;

有如下式子

p0 = dir·( |poc| - tca );

p1 = dir·( |poc| + tca );

要注意,沒有交點的時候, tca·tca < 0 是沒辦法開平方的

推導三維情況可以照上面的去做,dot能保證投影點在同乙個平面上的。

bool

intersect

(const ray& ray, const sphere& sphere, float& t0, float& t1)

return

true;

}

射線方程:ray : p(t) = o + d·t ( t >= 0 )

球的方程:sphere : sqr( p-c ) = r·r(

sqr(x) = x^2 = x·x)

o=origin, d=direction, c=center, r=radius

射線方程表明的是如下乙個點的集合p,當t從零增大時, d·t會沿著d向量的方向從零逐步變長,t 取值無限表示了射線單方向。從o點開始在d方向上無限個點構成了一條射線。

球的方程表明了任何點p,只要到c點的距離等於半徑r,則表明點在球面上,這麼乙個球面上的點的集合。

因此當射線與球相交的時候,這個點既在射線上,又在球面上。等式射線的p(t) = 球的p成立。

聯立兩個方程,試著求解 t 有:

s

qr( o + d·t - c ) = r·r

設 o-c=oc,有:

sqr( oc+d·t ) - r·r = 0

//展開得到如下式子

=> d·d·t·t + 2·oc·d·t + oc·oc - r·r = 0

=> (d·d)·t·t + 2·(oc·d)·t + oc·oc - r·r = 0

因為 d 是單位向量有d·d = dot(d, d) = 1最後方程為:

t·t + 2·(oc·d)·t +  oc·oc - r·r = 0;

這是乙個關於 t 的二次方程at^2 + bt + c = 0那麼解就已經出來了:

根據以上方程,我們其中試著展開 t 的式子

t0 = -(b + √δ) / 2a = -(b + √δ) / 2·1

= -b/2 - √(δ/4)

= -dot(oc, d) - √( sqr( dot(oc, d) ) - dot(oc, oc) + r·r )

求出 t 後可以根據p(t) = o + d * t得到交點。

附chai3d中的計算**

inline int cintersectionsegmentsphere(const cvector3d& a_segmentpointa,

const cvector3d& a_segmentpointb,

const cvector3d& a_spherepos,

const double& a_sphereradius,

cvector3d& a_collisionpoint0,

cvector3d& a_collisionnormal0,

cvector3d& a_collisionpoint1,

cvector3d& a_collisionnormal1)

double d = b*b - 4*a*c;

// segment ray is located outside of sphere

if (d < 0)

// segment ray intersects sphere

d = sqrt(d);

double e = 2.0 * a;

// compute both solutions

double u0 = (-b + d) / e;

double u1 = (-b - d) / e;

// check if the solutions are located along the segment ab

bool valid_u0 = ccontains(u0, 0.0, 1.0);

bool valid_u1 = ccontains(u1, 0.0, 1.0);

// two intersection points are located along segment ab

if (valid_u0 && valid_u1)

// compute point 0

ab.mulr(u0, a_collisionpoint0);

a_collisionpoint0.add(a_segmentpointa);

a_collisionpoint0.subr(a_spherepos, a_collisionnormal0);

a_collisionnormal0.normalize();

// compute point 1

ab.mulr(u1, a_collisionpoint1);

a_collisionpoint1.add(a_segmentpointa);

a_collisionpoint1.subr(a_spherepos, a_collisionnormal1);

a_collisionnormal1.normalize();

return (2);

}// one intersection point is located along segment ab

else if (valid_u0)

else

}// one intersection point is located along segment ab

else if (valid_u1)

else

}// both points are located outside of the segment ab

else

}

射線與球的相交性檢測

圖形碼農 2016 07 13 13 37 33 3718 收藏 1 分類專欄 碰撞檢測 從圖形來說 射線和圓相交,origin是射線起點,dir是射線的方向向量。p0,p1是兩個交點,center為圓心,半徑為r,d為圓心到射線的距離。我們先以2d切面圖來說明,當射線和圓相交的時候,可以看到,球心...

相交 光線與球

光線與球之間的相交很容易計算。如果光線的兩端分別是 x1,y1,z1 和 x2,y2,z2 則第一步是將光線引數化 x x1 x2 x1 t x1 it y y1 y2 y1 t y1 jt z z1 z2 z1 t z1 kt 其中0 t 1 中心在 l,m,n 半徑為r的球由下式給出 x l 2...

在3D中兩條射線的相交性檢測

摘自 3d數學基礎 圖形與遊戲開發 考慮在3d中兩條以引數形式定義的射線 vec t 1 vec t 1 vec vec t 2 vec t 2 vec 我們能夠解得它們的交點。暫時先不考慮 t 1,t 2 的取值範圍。因此,我們考慮的是無限長的射線 同樣,向量 vec,vec 也不必是單位向量。如...