直接上代码:

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

07-14 16:07