<h2>为了规范</h2>
<p>这个答案会比你的问题略为笼统(例如,我考虑的是一个长方体而不是一个立方体)。适应你的情况应该很简单。在</p>
<h2>一些定义</h2>
<pre><code>/*
Here is the cone in cone space:
+ ^
/|\ |
/*| \ | H
/ | \ |
/ \ |
+---------+ v
* = alpha (angle from edge to axis)
*/
struct Cone // In cone space (important)
{
double H;
double alpha;
};
/*
A 3d plane
v
^----------+
| |
| |
+----------> u
P
*/
struct Plane
{
double u;
double v;
Vector3D P;
};
// Now, a box.
// It is assumed that the values are coherent (that's only for this answer).
// On each plane, the coordinates are between 0 and 1 to be inside the face.
struct Box
{
Plane faces[6];
};
</code></pre>
<h2>线锥交点</h2>
<p>现在,让我们计算一个线段和圆锥的交点。请注意,我将在圆锥空间中进行计算。还要注意,我把Z轴作为垂直轴。把它改成Y轴是留给读者的练习。假定直线在圆锥空间中。段方向不是标准化的;相反,段是方向向量的长度,从<code>P</code>开始:</p>
^{pr2}$
<h2>直角圆锥交点</h2>
<p>现在,我们可以检查平面的矩形部分是否与圆锥体相交(这将用于检查立方体的一个面是否与圆锥体相交)。还在圆锥空间里。这项计划以一种有助于我们的方式通过:两个矢量和一个点。为了简化计算,向量没有被规范化。在</p>
<pre><code>/*
A point M in the plan 'rect' is defined by:
M = rect.P + a * rect.u + b * rect.v, where (a, b) are in [0;1]²
*/
bool intersect(Cone cone, Plane rect)
{
bool intersection = intersect(cone, rect.u, rect.P)
|| intersect(cone, rect.u, rect.P + rect.v)
|| intersect(cone, rect.v, rect.P)
|| intersect(cone, rect.v, rect.P + rect.u);
if(!intersection)
{
// It is possible that either the part of the plan lie
// entirely in the cone, or the inverse. We need to check.
Vector3D center = P + (u + v) / 2;
// Is the face inside the cone (<=> center is inside the cone) ?
if(center.Z >= 0 && center.Z <= cone.H)
{
double r = (H - center.Z) * tan(cone.alpha);
if(center.X * center.X + center.Y * center.Y <= r)
intersection = true;
}
// Is the cone inside the face (this one is more tricky) ?
// It can be resolved by finding whether the axis of the cone crosses the face.
// First, find the plane coefficient (descartes equation)
Vector3D n = rect.u.crossProduct(rect.v);
double d = -(rect.P.X * n.X + rect.P.Y * n.Y + rect.P.Z * n.Z);
// Now, being in the face (ie, coordinates in (u, v) are between 0 and 1)
// can be verified through scalar product
if(n.Z != 0)
{
Vector3D M(0, 0, -d/n.Z);
Vector3D MP = M - rect.P;
if(MP.scalar(rect.u) >= 0
|| MP.scalar(rect.u) <= 1
|| MP.scalar(rect.v) >= 0
|| MP.scalar(rect.v) <= 1)
intersection = true;
}
}
return intersection;
}
</code></pre>
<h2>箱锥交点</h2>
<p>现在,最后一部分:整个立方体:</p>
<pre><code>bool intersect(Cone cone, Box box)
{
return intersect(cone, box.faces[0])
|| intersect(cone, box.faces[1])
|| intersect(cone, box.faces[2])
|| intersect(cone, box.faces[3])
|| intersect(cone, box.faces[4])
|| intersect(cone, box.faces[5]);
}
</code></pre>
<h2>为了数学</h2>
<p>仍然在圆锥体空间中,圆锥体方程为:</p>
<pre><code>// 0 is the base, the vertex is at z = H
x² + y² = (H - z)² * tan²(alpha)
0 <= z <= H
</code></pre>
<p>现在,三维中直线的参数方程为:</p>
<pre><code>x = u + at
y = v + bt
z = w + ct
</code></pre>
<p>方向向量是(a,b,c),点(u,v,w)在直线上。在</p>
<p>现在,让我们把这些方程组合起来:</p>
<pre><code>(u + at)² + (v + bt)² = (H - w - ct)² * tan²(alpha)
</code></pre>
<p>然后,对该方程进行展开和重分解后,得到如下结果:</p>
<pre><code>At² + Bt + C = 0
</code></pre>
<p>其中A、B和C显示在第一个交集函数中。只需解决这个问题并检查z和t上的边界条件</p>