直接上代码:
using UnityEngine;
public class Calculate
{
//获取直线与球体的交点
public static Vector3[] GetLineSphereIntersections(Vector3 pointA, Vector3 pointB, Vector3 circlePosition, float circleRadius)
{
float cx = circlePosition.x;
float cy = circlePosition.y;
float cz = circlePosition.z;
float pAx = pointA.x;
float pAy = pointA.y;
float pAz = pointA.z;
float pBx = pointB.x;
float pBy = pointB.y;
float pBz = pointB.z;
float vx = pBx - pAx;
float vy = pBy - pAy;
float vz = pBz - pAz;
float A = vx * vx + vy * vy + vz * vz;
float B = 2 * (pAx * vx + pAy * vy + pAz * vz - vx * cx - vy * cy - vz * cz);
float C = pAx * pAx - 2 * pAx * cx + cx * cx + pAy * pAy - 2 * pAy * cy + cy * cy + pAz * pAz - 2 * pAz * cz + cz * cz - circleRadius * circleRadius;
float D = B * B - 4 * A * C;
if (D < 0) return new Vector3[0];
float t1 = (-B - Mathf.Sqrt(D)) / (2 * A);
Vector3 point1 = new Vector3(pAx * (1 - t1) + t1 * pBx, pAy * (1 - t1) + t1 * pBy, pAz * (1 - t1) + t1 * pBz);
if (D == 0) return new Vector3[] { point1 };
float t2 = (-B + Mathf.Sqrt(D)) / (2 * A);
Vector3 point2 = new Vector3(pAx * (1 - t2) + t2 * pBx, pAy * (1 - t2) + t2 * pBy, pAz * (1 - t2) + t2 * pBz);
if (Mathf.Abs(t1 - 0.5f) < Mathf.Abs(t2 - 0.5f)) return new Vector3[] { point1, point2 };
return new Vector3[] { point2, point1 };
}
//获取线段与球体的交点
public static Vector3[] GetSegmentSphereIntersections(Vector3 pointA, Vector3 pointB, Vector3 circlePosition, float circleRadius)
{
float cx = circlePosition.x;
float cy = circlePosition.y;
float cz = circlePosition.z;
float pAx = pointA.x;
float pAy = pointA.y;
float pAz = pointA.z;
float pBx = pointB.x;
float pBy = pointB.y;
float pBz = pointB.z;
float vx = pBx - pAx;
float vy = pBy - pAy;
float vz = pBz - pAz;
float A = vx * vx + vy * vy + vz * vz;
float B = 2 * (pAx * vx + pAy * vy + pAz * vz - vx * cx - vy * cy - vz * cz);
float C = pAx * pAx - 2 * pAx * cx + cx * cx + pAy * pAy - 2 * pAy * cy + cy * cy + pAz * pAz - 2 * pAz * cz + cz * cz - circleRadius * circleRadius;
float D = B * B - 4 * A * C;
if (D < 0) return new Vector3[0];
float t1 = (-B - Mathf.Sqrt(D)) / (2 * A);
float t2 = (-B + Mathf.Sqrt(D)) / (2 * A);
if ((t1 > 1 || t1 < 0) && (t2 > 1 || t2 < 0)) return new Vector3[0];
Vector3 point1 = new Vector3(pAx * (1 - t1) + t1 * pBx, pAy * (1 - t1) + t1 * pBy, pAz * (1 - t1) + t1 * pBz);
if (!(t1 > 1 || t1 < 0) && (t2 > 1 || t2 < 0)) return new[] { point1 };
if (Mathf.Approximately(D, 0)) return new[] { point1 };
Vector3 point2 = new Vector3(pAx * (1 - t2) + t2 * pBx, pAy * (1 - t2) + t2 * pBy, pAz * (1 - t2) + t2 * pBz);
if ((t1 > 1 || t1 < 0) && !(t2 > 1 || t2 < 0)) return new[] { point2 };
return new[] { point1, point2 };
}
}
想看解释,请移步:
https://www.codeproject.com/Articles/19799/Simple-Ray-Tracing-in-C-Part-II-Triangles-Intersec