2 def intersection(*entities
):
4 Finds the intersection between a list GeometryEntity instances. Returns a
5 list of all the intersections, Will raise a NotImplementedError exception
6 if unable to calculate the intersection.
10 >>> from sympy.geometry import *
11 >>> p1,p2,p3 = Point(0,0), Point(1,1), Point(-1, 5)
12 >>> l1, l2 = Line(p1, p2), Line(p3, p2)
14 >>> intersection(l1, p2)
16 >>> intersection(l1, l2)
18 >>> intersection(c, p2)
20 >>> intersection(c, Point(1, 0))
22 >>> intersection(c, l2)
23 [Point(1 - 1/5*5**(1/2), 1 + 2*5**(1/2)/5), Point(1 + 1/5*5**(1/2), 1 - 2*5**(1/2)/5)]
27 - The intersection of any geometrical entity with itself should return
28 a list with one item: the entity in question.
29 - An intersection requires two or more entities. If only a single
30 entity is given then one will receive an empty intersection list.
31 - It is possible for intersection() to miss intersections that one
32 knows exists because the required quantities were not fully
33 simplified internally.
35 from entity
import GeometryEntity
37 entities
= GeometryEntity
.extract_entities(entities
, False)
38 if len(entities
) <= 1: return []
40 res
= GeometryEntity
.do_intersection(entities
[0], entities
[1])
41 for entity
in entities
[2:]:
44 newres
.extend( GeometryEntity
.do_intersection(x
, entity
) )
49 def convex_hull(*args
):
51 Returns a Polygon representing the convex hull of a set of 2D points.
55 This can only be performed on a set of non-symbolic points.
59 >>> from sympy.geometry import Point
60 >>> points = [ Point(x) for x in [(1,1), (1,2), (3,1), (-5,2), (15,4)] ]
61 >>> convex_hull(points)
62 Polygon(Point(3, 1), Point(15, 4), Point(-5, 2), Point(1, 1))
64 Description of method used:
65 ===========================
66 See http://en.wikipedia.org/wiki/Graham_scan.
68 from point
import Point
69 from line
import Segment
70 from polygon
import Polygon
73 if isinstance(p
, Point
):
80 return Segment(p
[0], p
[1])
82 # Find lowest+rightmost point
84 for i
in xrange(1, len(p
)):
85 if (p
[i
][1] < p
[m
][1]) or ((p
[i
][1] == p
[m
][1]) and (p
[i
][0] > p
[m
][0])):
87 p
[0], p
[m
] = p
[m
], p
[0]
90 return (b
[0] - a
[0])*(c
[1] - a
[1]) - (c
[0] - a
[0])*(b
[1] - a
[1])
92 # Radial sort of points with respect to p[0] (our pivot)
102 x
= abs(p1
[0] - p0
[0]) - abs(p2
[0] - p0
[0])
103 y
= abs(p1
[1] - p0
[1]) - abs(p2
[1] - p0
[1])
104 if (x
< 0) or (y
< 0):
107 elif (x
> 0) or (y
> 0):
117 # Destroy points as found by sorting
118 for i
in xrange(len(p
)-1, -1, -1):
124 return (tarea(a
, b
, c
) > 0)
131 if isleft(p1
, p2
, p
[i
]):
138 def are_similar(e1
, e2
):
140 Returns True if e1 and e2 are similar (one can be uniformly scaled to
141 the other) or False otherwise.
145 - If the two objects are equal then they are always similar.
147 if e1
== e2
: return True
149 return e1
.is_similar(e2
)
150 except AttributeError:
152 return e2
.is_similar(e1
)
153 except AttributeError:
154 n1
= e1
.__class__
.__name
__
155 n2
= e2
.__class__
.__name
__
156 raise GeometryError("Cannot test similarity between %s and %s" % (n1
, n2
))