0

I have to draw an arc between two points at the edge of a circle. Assuming that the arc is drawn always in the shortest distance possible(edit2: sweep flag set to 0), I need to know if the arc is drawn clockwise or anticlockwise.

I got the following inputs:

  1. start point (point1)
  2. end point (point2)
  3. center point
  4. radius

enter image description here

Edit1: This question is related to arcs in svg. Hence its belongs to programming.

shaaaa
  • 425
  • 3
  • 7
  • 18
  • how on earth is this related to programming at all? Which geometry-lib are you talking about? Where is your code? – MakePeaceGreatAgain Mar 29 '22 at 08:53
  • 1
    I’m voting to close this question because it is not about programming, but purely about mathematics/geometry (that being said: draw a line through center and point 1 and look on which side of the line point 2 is) – Franz Gleichmann Mar 29 '22 at 08:54
  • SVG does not define CW/CCW of elliptic arc instead its defined as combination of larc/sweep flags along with the endpoints of your elliptic arc so the answer is arces might be both CW and CCW depends on occasion for more info see: [Converting an svg arc to lines](https://stackoverflow.com/a/41544540/2521214) .. so once you obtain the real center of arc you can use cross product to determine the CW/CCW ness of your arc – Spektre Mar 29 '22 at 10:29
  • @FranzGleichmann its about svg fileformat ... – Spektre Mar 29 '22 at 10:29
  • @MakePeaceGreatAgain its specific to SVG fileformat representation of elliptic arcs ... code nor lib is not important for this... – Spektre Mar 29 '22 at 10:32
  • but this site is about **programming**-issues, not about file-formats – MakePeaceGreatAgain Mar 29 '22 at 10:39
  • Find sign of cross product of vectors `point1-center` and `point2-center` to reveal shortest arc orientation – MBo Mar 29 '22 at 10:45
  • 2
    @MakePeaceGreatAgain the question is coming up when drawing arcs in svg. Hence its a programming question. – shaaaa Mar 29 '22 at 11:12

3 Answers3

1

The answer is SVG supports both clockwise and anticlockwise arcs. You switch between them by changing the "sweep" flag in an arc (A) command.

If you want to learn how SVG arcs work, the place to look is the Paths arcs section of the SVG specification.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
1

Having described data, you can find what arc is smaller - CCW or CW one.

Just check sign of cross product of vectors point1-center and point2-center to reveal shortest arc orientation:

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

For cp>0 you have to set sweep parameter to 0, otherwise to 1 (perhaps vice versa), whilst large-arc-flag should be always 0.

MBo
  • 77,366
  • 5
  • 53
  • 86
1

After discussing with a mathematician, I found an answer to this and based on that I wrote the following code:

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;

        }
shaaaa
  • 425
  • 3
  • 7
  • 18