Reputation: 3042
I am trying to write a Python or JavaScript routine that finds two point on an arc.
I will go in to the routine with a start_distance and end_distance. I want to move around the circumference of arc a given amount and then return the new x's and y's. In affect I am trying to move the start and end points of my arc.
My input to the routine will be
def get_points_on_an_arc(x1, y1, x2, y2, radius, large, clockwise, start_distance, end_distance)
# logic here
return s_x, s_y, e_x, e_y
Here is a image that might help you.
Any idea on how to write this?
Thanks
Upvotes: 3
Views: 1661
Reputation: 328
I have written this code:
class Circle:
def __init__(self, rds):
'''rds:radius delete:ctr:center of circle'''
self.rds = rds
def isoncircle(self, point):
'''a check if point is on circle'''
if point_on_circle:
return True
return False
def get_point(self, start=[0, 0], distance=2, direction='c'):
'''start:bottom point distance:distance to move up or down direction:move up or down'''
if direction == 'c':
cme = [start[0]+abs(distance-self.rds), start[1]+abs(distance-self.rds)]
elif direction == 'cou':
start = [start[0], start[1]-(self.rds*2)]
cme = [start[0]-abs(distance-self.rds), start[1]-abs(distance-self.rds)]
if self.isoncircle(cme):
return cme
def get_points(self, sd, ed):
s_x, s_y = self.get_point(distance=sd, direction='c')
e_x, e_y = self.get_point(distance=ed, direction='cou')
return s_x, s_y, e_x, e_y
circle = Circle(4)
circle.get_points(4, 4)
The init function does all the setting up.
The isoncircle function checks if a point is on the circle.
The get_point function gets an end point.
The get_points function sums it all up and gets the two end points.
Take a careful look and you can change the distances and even the start point in the get_point function.
If any of this is unclear, let me know.
Upvotes: 0
Reputation: 452
class Circle(object):
def __init__(self, center=(0,0), radius=1):
""" Center and radius define a unique circle """
self._center = center
self._radius = radius
...
def isOn(self, point):
if point_on_circle:
return True
return False
...
def get_new_point(self, start=(1,0), distance=1, direction='clockwise'):
""" Inputs:
circle - instance of the Circle() class
start - tuple of (x, y) the exists on circle
distance - distance to travel in radians
direction - 'clockwise' or 'widdershins'
"""
assert circle.isOn(start), "Start point is NOT on the circle"
# code to calculate new point here - basic geometry, use Google
end = ...
return end
def get_points_on_an_arc(self, x1, y1, x2, y2, large, clockwise, start_distance, end_distance):
""" Your function signature will ONLY work if it is a class method
The alternative is to change the signature and explicitly pass in a Circle() object to the function
"""
s_x, s_y = get_new_point(start=(x1, y1), distance=start_distance, direction='clockwise')
e_x, e_y = get_new_point(start=(x2, y2), distance=end_distance, direction='widdershins')
return s_x, s_y, e_x, e_y
Upvotes: 0
Reputation: 80187
At first you need to find circle center. It lies on middle perpendicular to P1-P2 segment. Middle point.
M = (P1 + P2)/2
P12 = P2-P1 = (P12.X, P12.Y)
Perpendicular to P12 vector is
PP = (-P12.Y, P12.X)
Center
C = M + PP * t
where t is parameter.
you need to solve equation
(C-P1)^2 = R^2
against t parameter, then choose one of two possible solutions to fulfill requirements (large, clockwise)
(for example, through sign of scalar product of CP1 and CP2)
When center is found, the rest of problem is easy: rotate P1 by (StartDistance/R) angle around the center, and rotate P2 by (-EndDistance/R) angle.
Upvotes: 2