算法代码参考如下:
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;
}
}