光线求交

  • 光线定义:position \(a(t)\) = \(o\) + \(t\vec{d}\);
  • 球定义: center p, radius r;
  • 平面定义:normal \(\vec{n}\) , offset t;
  • 三角形定义:position \(a_1\), \(a_2\), \(a_3\), normal \(\vec{n}\);

光线与球相交 (Ray/Sphere Intersection)

光线求交-面、三角形、球 (Ray intersection)-LMLPHP

光线求交-面、三角形、球 (Ray intersection)-LMLPHP

c++代码 :

bool HitTest(const Ray& ray, HitTestResult* result)
{
Vector eo = Center - ray.Position;
float v = eo * ray.Direction;
auto disc = Radius * Radius - (eo * eo) + v * v;
if (disc < 0) return false;
disc = v - sqrt(disc);
if (disc < 0.001f || disc >= ray.MaxDistance) return false;
result->Shape = const_cast<Sphere*>(this);
result->Normal = (disc * ray.Direction - eo).Normalize();
result->Distance = disc;
return true;
}

光线与平面相交 (Ray / Plane Intersection)

线与平面相交 Ray/Plane Intersection

平面在空间几何中可以用一个向量(法向量)和平面中的一点P0来表示。

平面就是满足下式的点集:\(\vec{n}(\vec{P}-\vec{P_0})= 0\)

得到:\(\vec{n}\cdot\vec{P}=d\); \(d=\vec{n}\cdot\vec{P_0}\);

给定射线r(t) = o +td,平面方程为n.p+d=0,将p(t)带入到平面方程,最后求得t:

\(t = (-d-(\vec{n}\cdot\vec{p_0}))/(\vec{n}\cdot\vec{d})\)

光线求交-面、三角形、球 (Ray intersection)-LMLPHP

光线求交-面、三角形、球 (Ray intersection)-LMLPHP

c++代码:

bool HitTest(const Ray& ray, HitTestResult* result)
{
auto denom = Normal * ray.Direction;
if (denom > 0) return false;
auto d = (Normal * ray.Position + Offset) / (-denom);
if (d >= ray.MaxDistance) return false;
result->Shape = const_cast<Plane*>(this);
result->Normal = Normal;
result->Distance = d;
return true;
}

光线与三角形相交 (Ray/Triangle Intersection)

  • 判断射线是否与平面相交
  • 判断点是否在三角形内
//构造函数:
Triangle(const Vector& Point1, const Vector& Point2, const Vector& Point3)
: Point1(Point1), Point2(Point2), Point3(Point3)
{
auto n1 = Point2 - Point1;
auto n2 = Point3 - Point1;
normal = Vector::Cross((Point2 - Point1), (Point3 - Point1)).Normalize();
} bool HitTest(const Ray& ray, HitTestResult* result)
{
float eo;
if (normal.Length() != 0 && (eo = ray.Direction * normal) < 0)
{
auto S = (Point1 - ray.Position) * normal / eo;
if (S < 0.001f || S >= ray.MaxDistance)
return false; auto V = S * ray.Direction + ray.Position; if (IsInner(V))
{
result->Shape = const_cast<Triangle*>(this);
result->Normal = normal;
result->Distance = S;
return true;
}
return false;
}
return false;
}

另一种方法:[用三角形重心求交

光线求交-面、三角形、球 (Ray intersection)-LMLPHP

05-11 22:52