Title: Find corner arcs for two points in Python
As I mentioned in my earlier post Connect two points with arcs of their midpoint circle in Python, 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 an ellipse and hence arcs connecting the points.
The previous example added the information that the ellipse should be a circle with center 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 find_corner_arcs method finds the two arcs that connect the points.
def find_corner_arcs(point1, point2):
'''Find 90 degree arcs connecting the two points.'''
# Find the rectangles' dimensions.
x_radius = abs(point1[0] - point2[0])
y_radius = abs(point1[1] - point2[1])
# If the points have the same X or Y coordinate, three's no solution.
if x_radius == 0 or y_radius == 0:
return None
# Make point1 be on the left.
if point2[0] < point1[0]:
point1, point2 = point2, point1
# See whether point1 is above or below point2.
if point1[1] < point2[1]:
# point1 is above point2.
rect1 = (
point1[0] - x_radius,
point1[1],
point1[0] + x_radius,
point1[1] + 2 * y_radius)
rect2 = (
point1[0],
point1[1] - y_radius,
point1[0] + 2 * x_radius,
point1[1] + y_radius)
start_angle1 = 0
start_angle2 = 180
else:
# point1 is below point2.
rect1 = (
point1[0] - x_radius,
point1[1] - 2 * y_radius,
point1[0] + x_radius,
point1[1])
rect2 = (
point1[0],
point1[1] - y_radius,
point1[0] + 2 * x_radius,
point1[1] + y_radius)
start_angle1 = -90
start_angle2 = 90
sweep1 = 90
sweep2 = 90
return rect1, start_angle1, sweep1, rect2, start_angle2, sweep2
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, so the function just returns None.
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 0 degrees (at the top of the red ellipse) and sweeps clockwise for 90 degrees.
The second rectangle, rect2, defines the blue ellipse. The blue arc starts at 180 degrees (at the bottom of the blue 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 as shown in the picture on the right. The method again uses the 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 blue ellipse. The blue arc starts at 180 degrees (at the left side of the blue 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 when we return None.
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 and download this one to see additional details.
My next post will use these corner arcs to draw rectangles with rounded corners.
|