Title: Connect two points with elliptical arcs in C#
As I mentioned in my earlier post Connect two points with arcs of midpoint circles in C#, two points alone cannot uniquely define a circle. An infinite number of circles (or ellipses) can pass through two points and therefore they can be connected by an infinite number of arcs. If you add extra information, however, two points can uniquely define a circle and hence arcs connecting the points.
The previous example added the information that the circle's center should be at the midpoint between the two points. This example takes a different approach. It creates two ellipses with sides that have the two points as midpoints, as shown in the picture at the top of the post. This isn't too hard. It's mostly a matter of examining the arrangement of the two points.
Finding Arcs
The following FindArcs method finds the two arcs that connect the points.
// Find 90 degree arcs connecting the two points.
private void FindArcs(PointF point1, PointF point2,
out RectangleF rect1, out RectangleF rect2,
out float start_angle1, out float start_angle2,
out float sweep_angle1, out float sweep_angle2)
{
// Find the rectangles' dimensions.
float x_radius = Math.Abs(point1.X  point2.X);
float y_radius = Math.Abs(point1.Y  point2.Y);
// If the points have the same X or Y coordinate,
// use midpoint circular arcs.
if ((x_radius == 0)  (y_radius == 0))
{
FindMidpointArcs(point1, point2,
out rect1, out rect2,
out start_angle1, out start_angle2,
out sweep_angle1, out sweep_angle2);
return;
}
// Make point1 be on the left.
if (point2.X < point1.X)
{
// Swap them.
PointF temp = point1;
point1 = point2;
point2 = temp;
}
// See whether point1 is above or below point2.
if (point1.Y < point2.Y)
{
// point1 is above point2.
rect1 = new RectangleF(
point1.X  x_radius,
point1.Y,
2 * x_radius,
2 * y_radius);
rect2 = new RectangleF(
point1.X,
point1.Y  y_radius,
2 * x_radius,
2 * y_radius);
start_angle1 = 90;
start_angle2 = 90;
}
else
{
// point1 is below point2.
rect1 = new RectangleF(
point1.X  x_radius,
point1.Y  2 * y_radius,
2 * x_radius,
2 * y_radius);
rect2 = new RectangleF(
point1.X,
point1.Y  y_radius,
2 * x_radius,
2 * y_radius);
start_angle1 = 0;
start_angle2 = 180;
}
sweep_angle1 = 90;
sweep_angle2 = 90;
}
The method first gets the horizontal and vertical distances between the two points. Those will become the ellipses' half axes lengths. (See the picture at the top of the post again to see how those values make sense.)
If either the X or Y radius is zero, then the points have the same X or Y coordinate. In that case you cannot make ellipses as shown in the picture to provide arcs to connect the points. We know that there are an infinite number of circles that touch the points, however, so wee can pick one. For this example I decided to use the FindMidpointArcs method used by the previous example to make arcs of a circle centered at the points' midpoint. See the previous example for details.
If the X and Y radii are not zero, the method switches point1 and point2 if necessary so point1 has the smaller X coordinate.
Now there are two cases.
Case 1: Point1 Lies Above Point2
In the first case, point1 has a smaller Y coordinate than point2. That situation is shown in the picture at the top of the post. In that case, the code uses geometry of the situation to construct the rectangles defining the ellipses.
In the picture at the top of the post, rect1 defines the red ellipse. The red arc starts at 90 degrees (at the top of the red ellipse) and sweeps clockwise for 90 degrees.
The second rectangle rect2 defines the green ellipse. The green arc starts at 90 degrees (at the bottom of the green ellipse) and also sweeps clockwise for 90 degrees.
Case 2: Point1 Lies Below Point2
In the second case, point1 has a larger Y coordinate than point2. That situation is shown in the picture on the right. The method again uses geometry of the situation to construct the rectangles defining the ellipses.
The rectangle rect1 again defines the red ellipse. This time the red arc starts at 0 degrees (at the right side of the red ellipse) and sweeps clockwise for 90 degrees.
The second rectangle rect2 defines the green ellipse. The green arc starts at 180 degrees (at the left side of the green ellipse) and also sweeps clockwise for 90 degrees.
The method's code finishes by setting both of the sweep angles to 90 degrees. Those angles are 90 degrees in all cases, except when the points' X or Y coordinates are the same. (In those cases the program uses circles centered at the points' midpoint, and the sweep angles are 180.)
Conclusion
The example's code that draws the bounding rectangles, ellipses, and arcs is similar to the code used by the previous example. See that example to see additional details.
Download the example to experiment with it and to see additional details.
