Circles of given radius through two points: Difference between revisions
Content added Content deleted
(Update to task description to add to special case exceptions to be handled.) |
(→{{header|Python}}: Update to handle r==0.0 special case.) |
||
Line 22: | Line 22: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
The function raises the ValueError exception for the special cases and usess try - except to catch these and extract the exception detail. |
|||
<lang python>from collections import namedtuple |
<lang python>from collections import namedtuple |
||
from math import sqrt |
from math import sqrt |
||
Line 30: | Line 32: | ||
def circles_from_p1p2r(p1, p2, r): |
def circles_from_p1p2r(p1, p2, r): |
||
'Following explanation at http://mathforum.org/library/drmath/view/53027.html' |
'Following explanation at http://mathforum.org/library/drmath/view/53027.html' |
||
if r == 0.0: |
|||
raise ValueError('radius of zero') |
|||
(x1, y1), (x2, y2) = p1, p2 |
(x1, y1), (x2, y2) = p1, p2 |
||
if p1 == p2: |
if p1 == p2: |
||
Line 56: | Line 60: | ||
for p1, p2, r in [(Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 2.0), |
for p1, p2, r in [(Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 2.0), |
||
(Pt(0.1234, 0.9876), Pt(0.1234, 0.9876), 2.0), |
(Pt(0.1234, 0.9876), Pt(0.1234, 0.9876), 2.0), |
||
(Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 0.5) |
(Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 0.5), |
||
(Pt(0.1234, 0.9876), Pt(0.1234, 0.9876), 0.0)]: |
|||
print('Through points:\n %r,\n %r\n and radius %f\nYou can construct the following circles:' |
print('Through points:\n %r,\n %r\n and radius %f\nYou can construct the following circles:' |
||
% (p1, p2, r)) |
% (p1, p2, r)) |
||
Line 93: | Line 98: | ||
and radius 0.500000 |
and radius 0.500000 |
||
You can construct the following circles: |
You can construct the following circles: |
||
ERROR: separation of points > diameter |
ERROR: separation of points > diameter |
||
Through points: |
|||
Pt(x=0.1234, y=0.9876), |
|||
Pt(x=0.1234, y=0.9876) |
|||
and radius 0.000000 |
|||
You can construct the following circles: |
|||
ERROR: radius of zero</pre> |
Revision as of 05:25, 17 April 2013
Circles of given radius through two points is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.
- Exceptions
- r==0.0 should be treated as never describing circles.
- If the points are coincident then an infinite number of circles with the point on their circumference can be drawn, unless r==0.0 as well which then collapses the circles to a point.
- If the points form a diameter then return two identical circles.
- If the points are too far apart then no circles can be drawn.
- Task detail
- Write a function/subroutine/method/... that takes two points and a radius and returns the two circles through those points, or some indication of special cases where two, possibly equal, circles cannot be returned.
- Show here the output for the following inputs:
p1 p2 r 0.1234, 0.9876 0.8765, 0.2345 2.0 0.0000, 2.0000 0.0000, 0.0000 1.0 0.1234, 0.9876 0.1234, 0.9876 2.0 0.1234, 0.9876 0.8765, 0.2345 0.5 0.1234, 0.9876 0.1234, 0.9876 0.0
- Ref
- Finding the Center of a Circle from 2 Points and Radius from Math forum @ Drexel
Python
The function raises the ValueError exception for the special cases and usess try - except to catch these and extract the exception detail.
<lang python>from collections import namedtuple from math import sqrt
Pt = namedtuple('Pt', 'x, y') Circle = Cir = namedtuple('Circle', 'x, y, r')
def circles_from_p1p2r(p1, p2, r):
'Following explanation at http://mathforum.org/library/drmath/view/53027.html' if r == 0.0: raise ValueError('radius of zero') (x1, y1), (x2, y2) = p1, p2 if p1 == p2: raise ValueError('coincident points gives infinite number of Circles') # delta x, delta y between points dx, dy = x2 - x1, y2 - y1 # dist between points q = sqrt(dx**2 + dy**2) if q > 2.0*r: raise ValueError('separation of points > diameter') # halfway point x3, y3 = (x1+x2)/2, (y1+y2)/2 # distance along the mirror line d = sqrt(r**2-(q/2)**2) # One answer c1 = Cir(x = x3 - d*dy/q, y = y3 + d*dx/q, r = abs(r)) # The other answer c2 = Cir(x = x3 + d*dy/q, y = y3 - d*dx/q, r = abs(r)) return c1, c2
if __name__ == '__main__':
for p1, p2, r in [(Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 2.0), (Pt(0.1234, 0.9876), Pt(0.1234, 0.9876), 2.0), (Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 0.5), (Pt(0.1234, 0.9876), Pt(0.1234, 0.9876), 0.0)]: print('Through points:\n %r,\n %r\n and radius %f\nYou can construct the following circles:' % (p1, p2, r)) try: print(' %r\n %r\n' % circles_from_p1p2r(p1, p2, r)) except ValueError as v: print(' ERROR: %s\n' % (v.args[0],))</lang>
- Output:
Through points: Pt(x=0.1234, y=0.9876), Pt(x=0.8765, y=0.2345) and radius 2.000000 You can construct the following circles: Circle(x=1.8631118016581893, y=1.974211801658189, r=2.0) Circle(x=-0.8632118016581896, y=-0.7521118016581892, r=2.0) Through points: Pt(x=0.0, y=2.0), Pt(x=0.0, y=0.0) and radius 1.000000 You can construct the following circles: Circle(x=0.0, y=1.0, r=1.0) Circle(x=0.0, y=1.0, r=1.0) Through points: Pt(x=0.1234, y=0.9876), Pt(x=0.1234, y=0.9876) and radius 2.000000 You can construct the following circles: ERROR: coincident points gives infinite number of Circles Through points: Pt(x=0.1234, y=0.9876), Pt(x=0.8765, y=0.2345) and radius 0.500000 You can construct the following circles: ERROR: separation of points > diameter Through points: Pt(x=0.1234, y=0.9876), Pt(x=0.1234, y=0.9876) and radius 0.000000 You can construct the following circles: ERROR: radius of zero