在求直线和椭圆弧的交点坐标的时候,我们同样和我上一个求直线和圆弧交点坐标一样,先来分析一下,主要分为
第一步: 求直线和椭圆弧交点,我们可以先求直线和椭圆弧的交点。
第二步:由于椭圆的可能是有角度的,椭圆圆心不在坐标轴的原点上,比如长轴不在X轴上,也不在Y轴上,这样的椭圆就是有角度的椭圆,这样的椭圆我们不好进行计算。对此,我们需要将圆弧旋转,然后再平移,使长轴在X轴上,是椭圆圆心在原点上,但是你会发现这样操作椭圆还是比较麻烦,因此,我们可以操作直线,想象椭圆圆心已经移动到了原点,因为移动椭圆只需要移动椭圆圆心就好,这样我们也根据移动椭圆圆心一样的步伐移动直线,然后求直线和假设移动后的椭圆的交点,然后根据椭圆圆心一样的步伐反向移动回去,得到的点就是直线和有角度的椭圆交点。(有点绕,可以画图理解哦)
第三步:最终通过判断交点是否在椭圆弧上。
下面开始展示代码,伸手党有福了,可能有些地方写的不好,望谅解,创作不易,喜欢给个好评吧。
主干
/// <summary>
/// 线段和椭圆弧的交点
/// </summary>
/// <param name="line">线段对象</param>
/// <param name="ht">存储交点和error信息</param>
/// <returns>返回交点和error信息</returns>
internal static Hashtable LineIntersectEllipticArc(Line line, Hashtable ht)
{
//线段的终点
Vector2 LineendPoint = line.endPoint;
//线段的起点
Vector2 LinestartPoint = line.startPoint;
//椭圆弧的长轴的一半
double maxAxis = 262.39051820125013 / 2;
//椭圆弧的短轴一半
double minAxis = 135.76528231694766 / 2;
//椭圆弧的起点
//椭圆弧的起始角度
double startAngle = DegreeToRadian(132.0438345714015);
//椭圆弧的终点
//椭圆弧的终止角度 //默认设置为90度对应的弧度
double endAngle = DegreeToRadian(258.13766538237763);
//椭圆弧的圆心
Vector2 center = new Vector2(17.7894639270817, 15.0254309579905);
//设置原点坐标(0,0)
Vector2 centerZero = new Vector2(0, 0);
//椭圆弧的导入角度'
double angle = DegreeToRadian(191.75357833501226);
//将直线顺时针旋转angle度
Vector2[] ve = Anticlockwise(LineendPoint, LinestartPoint, center, angle);
//假设默认交点坐标
Vector2 ptInter1 = new Vector2(0, 0);
Vector2 ptInter2 = new Vector2(0, 0);
//直线和椭圆的交点坐标
LineIntersectEllipse(MoveOne(ve[0], center), MoveOne(ve[1], center), maxAxis, minAxis, ref ptInter1, ref ptInter2);
//用于存储交点
List<Vector2> node = new List<Vector2>();
//用于判断是否有交点
bool judgeNode = false;
//存储的版本号
int version = 0;
double a = NormalizeRadianAngle(startAngle);
double b = NormalizeRadianAngle(endAngle);
if (Zero(ptInter1))
{
JudgeDotQualified(centerZero, ptInter1, a, b, node);
if (node.Count == 1)
{
if (node[0] != null)
{
//表示第一次有一个值
//将交点逆时针旋转
Vector2[] ve1 = Anticlockwise(ptInter1, ptInter2, centerZero, angle, false);
//再将交点平移得到最后真正的交点
ve1[0] = MoveTwo(ve1[0], center);
node[0] = ve1[0];
version = 1;
}
}
}
if (Zero(ptInter2))
{
if (version == 0)
{
JudgeDotQualified(centerZero, ptInter2, a, b, node);
if (node.Count == 1)
{
if (node[0] != null)
{
//表示第一次没有一个值
//将交点逆时针旋转