Problems drawing arc

I have some problems when trying to draw a 3D arc from 3 known points.

I've calculated the center of the circle and its radius.

Then, from the center and from 2 of the known points I've created 2 vectors OA and OB, from which I found the normal to the circle's plane by using the cross product of the 2 vectors, OA x OB.

The problem is that depending on which of the 3 known points I use as A and B (the normal will differ in magnitude but still have the same direction as it is perpendicular to the circle's plane by definition) the arc is drawn differently, not only because the direction of the plane, but also it seems to interfere somehow with the start and end angles.

Can you please explain how arc.CircleNormal is defined exactly?
How start and end angles are defined? (when is one point start and one end and not the other way around?)
And is zeroAngleDirection needed, what is its default option and its definition?

Thank you,
The ZeroAngleDirection property defines the Vector3D that specifies the 3D direction where the angle is zero. So if StartAngle is 0, then the arc will start in the direction of ZeroAngleDirection  (CenterPosition + ZeroAngleDirection * Radius * HorizontalStretchFactor). The direction of the arc is in the clockwise direction - from StartAngle to EndAngle.

For example the arc from the Ab3d.PowerToys samples is defined as
<visuals:LineArcVisual3D CircleCenterPosition="150,0,-100" Radius="50" StartAngle="0" EndAngle="270"
                        CircleNormal="0 1 0" ZeroAngleDirection="1 0 0"
                        LineColor="Silver" LineThickness="3"/>

Here the normal points up and the ZeroAngleDirection points in the x axis direction (let's say that this is to the right). The StartAngle is set to 0 so this means that the arc will start at the right side. Its EndAngle is set to 270. So this means that the arc will be drawn in the clockwise direction from 0 to 270 degrees - so from the right, then to the bottom (z direction), to the left and end on top (in -z direction) showin 3/4 of the circle.

Here is the source of the code that defines the arc positions:
       public static void AddArc3DPoints(Point3D circleCenterPosition,
                                         Vector3D circleNormal,
                                         Vector3D zeroAngleDirection,
                                         double xRadius, // radius at zero angle direction
                                         double yRadius,
                                         double startAngle,
                                         double endAngle,
                                         int segments,
                                         Point3DCollection points)
           if (startAngle == endAngle)

           var rightDirection = Vector3D.CrossProduct(zeroAngleDirection, circleNormal);

           var angleStep = ((endAngle - startAngle) * Math.PI / 180) / segments;

           var angle = startAngle * Math.PI / 180;
           for (int i = 0; i <= segments; i++)
               // Get the position in 3D based on the orientation of the circle (circleNormal, zeroAngleDirection)
               var onePosition = circleCenterPosition;
               onePosition += Math.Sin(angle) * yRadius * rightDirection;
               onePosition += Math.Cos(angle) * xRadius * zeroAngleDirection;

               // Add position

               if (i == segments - 1)
                   angle = endAngle * Math.PI / 180; // this prevents double inprecission
                   angle += angleStep;
Andrej Benedik
Hello Abenedik,

Thank you for your lengthy answer.

But, unfortunately, I still don't understand what zeroAngleDirection vector is.

1. what is it's point of origin ?
2. and it points to the point on the circle where it's angle is 0, but where is that?

Can you give an example of how it is calculated?

Thank you,
Hm, let's go to a 2D space.

For example, you want to draw a simple arc to a 2D coordinate system from angle 0 to angle 270 in a clockwise direction.

Usually, the angle 0 started on the x axis and the arc progresses downwards, crosses the -y axis, then -x axis and stops at the +y axis. In this case the zeroAngleDirection is (1, 0) - a 2D vector in the x direction. To get the first point on the arc, you start with the center position and add a zeroAngleDirection multiplied by the radius.

But we could also say, that the arc's zero angle starts at the +y axis (on top) - in this case the zeroAngleDirection would be (0, 1). In 2D this is actually not needed because if 0 angle is always on +x axis we still can define all possible arc shapes with different start and end angles.

But in 3D there are many more options - the arc can be oriented on xz plane, or on xy plane or in any other direction. To provide all those options we need to specify a 3D vector that specify in which direction the arc's zero angle is pointing - this also defines the plane on which the arc is drawn (the plane is define by normal and zeroAngleDirection).

The best way to understand that is to open Visual Studio designer with a Viewport3D. Then add a ColoredAxisVisual3D so that you will see into which directions the axes are pointing and then add a LineArcVisucl3D - then in designer change the value of zeroAngleDirection and you should immediately see the results.
Andrej Benedik

Forum Jump:

Users browsing this thread:
1 Guest(s)