ARC在SVG中是顺时针还是逆时针?

Is ARC clockwise or counterclockwise In SVG?

我必须在圆的边缘的两点之间画一条弧。假设弧线总是以尽可能短的距离绘制(edit2:扫描标志设置为 0),我需要知道弧线是顺时针还是逆时针绘制的。

我得到以下输入:

  1. 起点(point1)
  2. 终点(point2)
  3. 中心点
  4. 半径

Edit1:这个问题与 svg 中的弧线有关。因此它属于编程。

答案是SVG支持顺时针和逆时针弧。您可以通过更改弧 (A) 命令中的“扫描”标志在它们之间切换。

如果您想了解 SVG 弧的工作原理,可以查看 Paths arcs section of the SVG specification

根据描述的数据,您可以找到更小的圆弧 - CCW 或 CW。

只需检查向量 point1-centerpoint2-center 的叉积符号即可揭示最短弧方向:

cp = (p1.x-c.x)*(p2.y-c.y)-(p1.y-c.y)*(p2.x-c.x)

对于 cp>0 你必须将 sweep 参数设置为 0,否则设置为 1 (反之亦然),而 large-arc-flag 应该总是 0.

在与数学家讨论后,我找到了答案,并在此基础上编写了以下代码:

public static bool IsClockWise(Point point1, Point point2, Circle circle)
        {
            var dxPoint1 = point1.X - circle.CenterX;
            var dyPoint1 = point1.Y - circle.CenterY;
            var dxPoint2 = point2.X - circle.CenterX;
            var dyPoint2 = point2.Y - circle.CenterY;


            double thetaPoint1 = 0, thetaPoint2 = 0;
            if (dxPoint1 > 0 && dyPoint1 >= 0)
                thetaPoint1 = Math.Asin(dyPoint1 / circle.Radius);
            else if (dxPoint1 <= 0 && dyPoint1 > 0)
                thetaPoint1 = Math.PI - Math.Asin(dyPoint1 / circle.Radius);
            else if (dxPoint1 < 0 && dyPoint1 <= 0)
                thetaPoint1 = Math.Abs(Math.Asin(dyPoint1 / circle.Radius)) + Math.PI;
            else if (dxPoint1 >= 0 && dyPoint1 < 0)
                thetaPoint1 = 2 * Math.PI - Math.Abs(Math.Asin(dyPoint1 / circle.Radius));

            if (dxPoint2 > 0 && dyPoint2 >= 0)
                thetaPoint2 = Math.Asin(dyPoint2 / circle.Radius);
            else if (dxPoint2 <= 0 && dyPoint2 > 0)
                thetaPoint2 = Math.PI - Math.Asin(dyPoint2 / circle.Radius);
            else if (dxPoint2 < 0 && dyPoint2 <= 0)
                thetaPoint2 = Math.Abs(Math.Asin(dyPoint2 / circle.Radius)) + Math.PI;
            else if (dxPoint2 >= 0 && dyPoint2 < 0)
                thetaPoint2 = 2 * Math.PI - Math.Abs(Math.Asin(dyPoint2 / circle.Radius));

            if (thetaPoint1 > thetaPoint2)
            {
                return !(thetaPoint1 - thetaPoint2 <= Math.PI);
            }

            return thetaPoint2 - thetaPoint1 <= Math.PI;

        }