圖形碼農 2016-07-13 13:37:33
3718
收藏 1
分類專欄: 碰撞檢測
從圖形來說
射線和圓相交, 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 有:
sqr( 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那麼解就已經出來了:
= 4·sqr( oc·d ) - 4·( oc·oc - r·r )
= 4·( sqr( oc·d ) - oc·oc + r·r );
如果判別式 δ > 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
}
射線與球的相交性檢測
射線和圓相交,origin是射線起點,dir是射線的方向向量。p0,p1是兩個交點,center為圓心,半徑為r,d為圓心到射線的距離。我們先以2d切面圖來說明,當射線和圓相交的時候,可以看到,球心 center 到射線 ray 的距離 d r,這個即為相交的條件。那麼射線與球相切就轉化為了球心到射...
相交 光線與球
光線與球之間的相交很容易計算。如果光線的兩端分別是 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 也不必是單位向量。如...