直线和线段与球体的交点算法参考

直接上代码:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值