求两个圆交点的算法和圆与直线交点算法

36 篇文章 1 订阅
21 篇文章 1 订阅

算法代码参考如下:

using System;
using UnityEngine;

[Serializable]
public struct Circle
{
	public Vector2 center;
	public float radius;
}

[Serializable]
public struct Segment
{
	public Vector2 pointA;
	public Vector2 pointB;
}

public class CircleIntersect
{
	static public bool TryCircleIntersect(Circle circleA, Circle circleB, out Vector2 p0, out Vector2 p1)
	{
		float dist, a, h;
		p0 = Vector2.zero;
		p1 = Vector2.zero;

		dist = Vector3.Distance(circleA.center, circleB.center);

		if (dist > circleA.radius + circleB.radius) return false;
		if (Vector2.Distance(circleB.center, circleA.center) + circleA.radius < circleB.radius) return false;
		if (Vector2.Distance(circleB.center, circleA.center) + circleB.radius < circleA.radius) return false;
		//
		a = (circleA.radius * circleA.radius - circleB.radius * circleB.radius + dist * dist) / (2 * dist);
		h = Mathf.Sqrt(circleA.radius * circleA.radius - a * a);

		Vector2 P2 = (circleB.center - circleA.center);
		P2 = (P2 * (a / dist));
		P2 = (P2 + circleA.center);

		float x0, y0, x1, y1 = 0;

		x0 = P2.x + h * (circleB.center.y - circleA.center.y) / dist;
		y0 = P2.y - h * (circleB.center.x - circleA.center.x) / dist;

		x1 = P2.x - h * (circleB.center.y - circleA.center.y) / dist;
		y1 = P2.y + h * (circleB.center.x - circleA.center.x) / dist; ;

		p0 = new Vector2(x0, y0);
		p1 = new Vector2(x1, y1);

		return true;
	}

	static public int TrySegmentIntersect(Circle circle, Segment segment, out Vector2 p0, out Vector2 p1)
	{
		float t;

		var dx = segment.pointB.x - segment.pointA.x;
		var dy = segment.pointB.y - segment.pointA.y;

		var a = dx * dx + dy * dy;
		var b = 2 * (dx * (segment.pointA.x - circle.center.x) + dy * (segment.pointA.y - circle.center.y));
		var c = (segment.pointA.x - circle.center.x) * (segment.pointA.x - circle.center.x) + (segment.pointA.y - circle.center.y) * (segment.pointA.y - circle.center.y) - circle.radius * circle.radius;

		var determinate = b * b - 4 * a * c;
		if ((a <= 0.0000001) || (determinate < -0.0000001))
		{
			p0 = Vector2.zero;
			p1 = Vector2.zero;
			return 0;
		}
		if (determinate < 0.0000001 && determinate > -0.0000001)
		{
			t = -b / (2 * a);
			p0 = new Vector2(segment.pointA.x + t * dx, segment.pointA.y + t * dy);
			p1 = Vector2.zero;
			return 1;
		}

		t = (float)((-b + Mathf.Sqrt(determinate)) / (2 * a));
		p0 = new Vector2(segment.pointA.x + t * dx, segment.pointA.y + t * dy);
		t = (float)((-b - Mathf.Sqrt(determinate)) / (2 * a));
		p1 = new Vector2(segment.pointA.x + t * dx, segment.pointA.y + t * dy);

		return 2;
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本程序是两相交交点,输入信息为两心坐标和半径值。如有更好的算法,欢迎交流!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值