!Cv      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b cdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                     !!"""""""""""""""""""""""""""#$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%% % % % % &&&&&&&&&&&&&&&&&&& &!'"'#'$'%'&'''(')'*'+','-'.'/'0'1'2'3'4'5'6'7'8'9':';'<'='>'?'@'A'B'C'D'E'F(G(H(I(J(K(L(M(N(O(P(Q(R(S(T(U(V(W(X(Y(Z([(\(](^(_(`)a)b)c)d)e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*{*|*}*~***++++++++++++++++++++++++++,,,,,,,,,,,,,,,,,,,,-------------------...////////////////////////////////////00000000000000000000011111111111 1 1 1 1 1111111111111111111 1!1"1#1$1%1&2'2(2)2*2+2,2-2.2/202122232425262728292:2;2<2=2>2?2@2A2B2C3D3E3F3G3H3I3J3K3L3M3N3O3P3Q3R3S3T3U3V3W3X3Y3Z3[3\3]3^3_3`3a3b3c3d3e3f3g3h3i3j3k3l4m4n4o4p4q4r4s4t4u4v4w4x4y4z4{4|4}4~4445555555555555566666666666666666666666666666666666666666666777777777777777777777777777778888999999999999999999::::::::3;;;;;;;;;;;;;; ; ; ; ; <<====>>>??@AAAAAAA B!B"B#B$B%B&C'C(C)C*C+C,C-D.D/D0D1D2D3E4E5E6E7E8F9F:F;F<F=F>F?G@GAGBCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~HHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ J J J J JJJJJJJJJJJJJJKKKKK L!L"L#L$L%M&M'M(M)M*M+M,M-M.M/M0M1M2M3M4M5M6M7M8M9M:M;M<M=M>M?M@MAMBMCMDMEMFNGNHNINJNKNLNMNNOOOPOQOROSOTOUOVOWOXOYOZO[P\P]P^P_P`PaPbPcPdPePfPgPhPiPjPkPlPmPnQoQpQqQrRsRtRuRvRwRxRyRzR{R|R}R~RRRRRRRRRRRRRRSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUVVVVVVVVVVVVVVVVVVVVWWWWiXNone%&',-.14567=>?@AHMPSUVX_gkg+ hgeometry)Test if the expression has any variables.YNone%&',-.14567=>?@AHMPSUVX_gklP hgeometryThe sign of an expressionT hgeometryGGiven the terms, in decreasing order of significance, computes the signVi.e. expects a list of terms, we base the sign on the sign of the first non-zero term.0pre: the list contains at least one such a term.PRQSTNone%&',-.14567=>?@AHMPSUVX_gk9 hgeometryoThe word specifiies how many *duplicates* there are. I.e. If the Bag maps k to i, then k has multiplicity i+1.U hgeometry:Represents a Sum of terms, i.e. a value that has the form:! \sum c \Pi_i \varepsilon(i) >The terms are represented in order of decreasing significance.AThe main idea in this type is that, if symbolic values contains \varepsilon(i)T terms we can always order them. That is, two Symbolic terms will be equal only if:3they contain *only* a constant term (that is equal)they contain the exact same  \varepsilon-fold.V hgeometry%A term 'Term c es' represents a term:" c \Pi_{i \in es} \varepsilon(i) 0for a constant c and an arbitrarily small value  \varepsilon, parameterized by i.Y hgeometryGets the factorsZ hgeometryCreates the term \varepsilon(i)\ hgeometrycomputes a base d that can be used as:$ \varepsilon(i) = \varepsilon^{d^i} ] hgeometry=Test if the epsfold has no pertubation at all (i.e. if it is \Pi_{\emptyset}^ hgeometryLens to access the constant c in the term._ hgeometryCreates a singleton term` hgeometry=Produces a list of terms, in decreasing order of significancea hgeometry>Computing the Sign of an expression. (Nothing represents zero)b hgeometry!Creates a constant symbolic valuec hgeometryiCreates a symbolic vlaue with a single indexed term. If you just need a constant (i.e. non-indexed), use bd hgeometry@given the value c and the index i, creates the perturbed value c + \varepsilon(i) hgeometry'Computes the difference of the two maps hgeometry-maximum multiplicity of an element in the bagUVWXYZ[\]^_`abcdXZ[]Y\VW_^Ubcd`aNone%&',-.14567=>?@AHMPSUVX_gk% hgeometryIntercardinal directions hgeometry1Computes the direction opposite to the given one. hgeometrydGet the two intercardinal directions, in increasing order, corresponding to the cardinal direction.}~}~None%&',-.14567=>?@AHMPSUVX_gk hgeometry,Open on left endpoint; so Closed before open hgeometry.Order on right endpoint; so Open before Closed (C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.145678=>?@ADHMPSTUVX_gkL hgeometry=A type family for types that have an associated numeric type. hgeometryA type family for types that are associated with a dimension. The dimension is the dimension of the geometry they are embedded in.  None%&',-.14567=>?@AHMPSUVX_gk hgeometryAn Interval is essentially a Z[ but with possible payload-We can think of an interval being defined as:Ddata Interval a r = Interval (EndPoint (r :+ a)) (EndPoint (r :+ a)) hgeometry!Constrct an interval from a Range hgeometryTest if a value lies in an interval. Note that the difference between inInterval and inRange is that the extra value is *not* used in the comparison with inInterval, whereas it is in inRange. hgeometry(Shifts the interval to the left by delta hgeometrynMakes sure the start and endpoint are oriented such that the starting value is smaller than the ending value. hgeometry-Flips the start and endpoint of the interval.-  None%&',-.14567=>?@AHMPSUVX_gk  hgeometry1Information stored in a node of the Interval Tree hgeometry.IntervalTree type, storing intervals of type i hgeometry$Anything that looks like an interval hgeometry8Given an ordered list of points, create an interval treeO(n) hgeometryBuild an interval tree O(n \log n) hgeometry@Lists the intervals. We don't guarantee anything about the orderrunning time: O(n). hgeometryFind all intervals that stab x O(\log n + k), where k is the output size hgeometryFind all intervals that stab x O(\log n + k), where k is the output size hgeometry@Insert : pre: the interval intersects some midpoint in the tree O(\log n) hgeometry Delete an interval from the Tree O(\log n)) (under some general position assumption) None%&',-.14567=>?@AHMPSUVX_gkx (C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gko hgeometryOInternal nodes store a split point, the range, and an associated data structure hgeometryCLeaf nodes store an atomic range, and an associated data structure. hgeometry.We store atomic ranges a bit more efficiently.* hgeometry(Segment tree on a Fixed set of endpoints7 hgeometryInterval: hgeometry%Class for associcated data structures> hgeometryNGiven a sorted list of endpoints, without duplicates, construct a segment treeO(n) time hgeometryInterleaves the two lists8interleave (NonEmpty.fromList ["0","1","2"]) ["01","12"]"0" :| ["01","1","12","2"]? hgeometryBuild a SegmentTree O(n \log n)@ hgeometry'Search for all intervals intersecting x O(\log n + k) where k is the output sizeA hgeometryBReturns the associated values of the nodes on the search path to x O(\log n) hgeometry(Gets the range associated with this nodeB hgeometryNPre: the interval should have one of the endpoints on which the tree is built.C hgeometry Delete an interval from the tree pre: The segment is in the tree!"*+,-.456789:;<=>?@ABCD"-.*+,=:;<>?BC@A789D456\None%&',-.14567=>?@AHMPSUVX_gkÝ"*+,-.456789:;<=>?@ABCDNone%&',-.14567=>?@AHMPSUVX_gkӸc hgeometrysDatatype representing d dimensional vectors. Our implementation wraps the implementation provided by fixed-vector.f hgeometry.A proxy which can be used for the coordinates.j hgeometry-Pattern synonym for two and three dim vectorsl hgeometryLens into the i th elementm hgeometry Similar to lx above. Except that we don't have a static guarantee that the index is in bounds. Hence, we can only return a Traversalp hgeometry!Get the head and tail of a vectorq hgeometry.Cross product of two three-dimensional vectorsr hgeometryVonversion to a Linear.V2s hgeometryConversion to a Linear.V3t hgeometryConversion from a Linear.V3u hgeometry(Add an element at the back of the vectorv hgeometry)Get a vector of the first d - 1 elements.x hgeometry&Get a prefix of i elements of a vectory hgeometry Construct a 2 dimensional vectorz hgeometry Construct a 3 dimensional vector{ hgeometry#Destruct a 2 dim vector into a paircdefghijklmnopqrstuvwxyz{|fgcdeklmnopqrstuvwxyz{|jihNone%&',-.14567=>?@AHMPSUVX_gkڬ hgeometryGMapping between the implementation type, and the actual implementation. hgeometryDatatype representing d dimensional vectors. The default implementation is based n VectorFixed. However, for small vectors we automatically select a more efficient representation. hgeometry!Get the head and tail of a vector(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk hgeometryDatatype representing d dimensional vectors. The default implementation is based n VectorFixed. However, for small vectors we automatically select a more efficient representation. hgeometryLens into the i th element hgeometry Similar to x above. Except that we don't have a static guarantee that the index is in bounds. Hence, we can only return a Traversal hgeometry(Add an element at the back of the vector hgeometry)Get a vector of the first d - 1 elements. hgeometry&Get a prefix of i elements of a vector hgeometry.Cross product of two three-dimensional vectors(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk hgeometry='isScalarmultipleof u v' test if v is a scalar multiple of u. .Vector2 1 1 `isScalarMultipleOf` Vector2 10 10True3Vector3 1 1 2 `isScalarMultipleOf` Vector3 10 10 20True-Vector2 1 1 `isScalarMultipleOf` Vector2 10 1False2Vector2 1 1 `isScalarMultipleOf` Vector2 (-1) (-1)True2Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.1True2Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.2False2Vector2 2 1 `isScalarMultipleOf` Vector2 11.1 11.2False,Vector2 2 1 `isScalarMultipleOf` Vector2 4 2True,Vector2 2 1 `isScalarMultipleOf` Vector2 4 0False0Vector3 2 1 0 `isScalarMultipleOf` Vector3 4 0 5False0Vector3 0 0 0 `isScalarMultipleOf` Vector3 4 0 5True hgeometryPscalarMultiple u v computes the scalar labmda s.t. v = lambda * u (if it exists) hgeometry'Actual implementation of scalarMultiple;45:9876;<>=?@ABCDEFGHONMLKJIfg$?@ABCDEFGHONMLKJIfg:9876=54><;](C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk hgeometryPTypes that we can transform by mapping a function on each point in the structure hgeometryA d-dimensional point. hgeometrySimilarly, we can write::{ let& g :: Point 3 r -> r g (Point3 x y z) = z in g myPoint:}3 hgeometry(Pattern synonym for 2 dimensional points:{ let$ f :: Point 2 r -> r f (Point2 x y) = x in f (Point2 1 2):}1 hgeometryRWe provide pattern synonyms for 1, 2 and 3 dimensional points. i.e. we can write::{ let+ f :: Num r => Point 1 r -> r f (Point1 x) = x + 1 in f (Point1 1):}2 hgeometry-Point representing the origin in d dimensionsorigin :: Point 4 IntPoint4 [0,0,0,0] hgeometry6Lens to access the vector corresponding to this point.(Point3 1 2 3) ^. vectorVector3 [1,2,3] origin & vector .~ Vector3 1 2 3Point3 [1,2,3] hgeometry{Get the coordinate in a given dimension. This operation is unsafe in the sense that no bounds are checked. Consider using  instead.Point3 1 2 3 ^. unsafeCoord 22 hgeometry'Get the coordinate in a given dimension Point3 1 2 3 ^. coord (C :: C 2)2%Point3 1 2 3 & coord (C :: C 1) .~ 10Point3 [10,2,3]'Point3 1 2 3 & coord (C :: C 3) %~ (+1)Point3 [1,2,4] hgeometryjConstructs a point from a list of coordinates. The length of the list has to match the dimension exactly.,pointFromList [1,2,3] :: Maybe (Point 3 Int)Just Point3 [1,2,3](pointFromList [1] :: Maybe (Point 3 Int)Nothing.pointFromList [1,2,3,4] :: Maybe (Point 3 Int)Nothing hgeometry,Project a point down into a lower dimension. hgeometry)Compare by distance to the first argument hgeometry-Squared Euclidean distance between two points hgeometry%Euclidean distance between two points^None%&',-.14567=>?@AHMPSUVX_gk*<  hgeometryeData type for expressing the orientation of three points, with the option of allowing Colinearities. hgeometryTGiven three points p q and r determine the orientation when going from p to r via q.  hgeometryTGiven three points p q and r determine the orientation when going from p to r via q.  hgeometrySort the points arround the given point p in counter clockwise order with respect to the rightward horizontal ray starting from p. If two points q and r are colinear with p, the closest one to p is reported first. running time: O(n log n)  hgeometryGiven a zero vector z, a center c, and two points p and q, compute the ccw ordering of p and q around c with this vector as zero direction.pre: the points p,q /= c  hgeometryGiven a zero vector z, a center c, and two points p and q, compute the cw ordering of p and q around c with this vector as zero direction.pre: the points p,q /= c  hgeometrykCounter clockwise ordering of the points around c. Points are ordered with respect to the positive x-axis. hgeometrycClockwise ordering of the points around c. Points are ordered with respect to the positive x-axis. hgeometryGiven a center c, a new point p, and a list of points ps, sorted in counter clockwise order around c. Insert p into the cyclic order. The focus of the returned cyclic list is the new point p.running time: O(n)      _None%&',-.14567=>?@AHMPSUVX_gk1D hgeometry,Shorthand to access the first coordinate C 1Point3 1 2 3 ^. xCoord1Point2 1 2 & xCoord .~ 10 Point2 [10,2] hgeometry-Shorthand to access the second coordinate C 2Point2 1 2 ^. yCoord2Point3 1 2 3 & yCoord %~ (+1)Point3 [1,3,3] hgeometry,Shorthand to access the third coordinate C 3Point3 1 2 3 ^. zCoord3Point3 1 2 3 & zCoord %~ (+1)Point3 [1,2,4] `None%&',-.14567=>?@AHMPSUVX_gk= hgeometry1Quadrants of two dimensional points. in CCW order hgeometryQuadrants around point c; quadrants are closed on their "previous" boundary (i..e the boundary with the previous quadrant in the CCW order), open on next boundary. The origin itself is assigned the topRight quadrant hgeometry$Quadrants with respect to the origin hgeometrygGiven a center point c, and a set of points, partition the points into quadrants around c (based on their x and y coordinates). The quadrants are reported in the order topLeft, topRight, bottomLeft, bottomRight. The points are in the same order as they were in the original input lists. Points with the same x-or y coordinate as p, are "rounded" to above.(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk?+     +     None%&',-.14567=>?@AHMPSUVX_gkN " hgeometryA generic (1D) range tree. The rE parameter indicates the type of the coordinates of the points. The qZ represents any associated data values with those points (stored in the leaves), and the v5 types represents the data stored at internal nodes.* hgeometryCreates a range tree+ hgeometry+pre: input is sorted and grouped by x-coord, hgeometry$Lists all points in increasing orderrunning time: O(n)- hgeometry Range searchrunning time:  O(\log n). hgeometry>Range search, report the (associated data structures of the)  O(\log n)G nodes that form the disjoint union of the range we are querying with.running time:  O(\log n)/ hgeometryThe actual search0 hgeometry7Helper function to get the range of a binary leaf tree1 hgeometryGet the range of a node5 hgeometryPerform a counting query !"#$%&(')*+,-./012345%&(')"#$*+,-./0123 !45None%&',-.14567=>?@AHMPSUVX_gkQGT hgeometry!Gets all points in the range treeDEFGHIJKLMNOPQRSTUVWQNOPKLMJGHIFRSTUVWDE(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk`g hgeometrybA priority search tree storing points in (mathbb{R}^2) that have an additional payload of type p. hgeometryqInternal nodes store the max x-value from the left subtree and the point that has globally the max-y coordinate.j hgeometryFCreates a Priority Search Tree for 3-sided range queries of the form _l,x_r] \times [y,\infty).the base tree will be static.)pre: all points have unique x-coordinatesrunning time:  O(n\log n) hgeometry-Inserts a point into the priority search treerunning time:  O(\log n)k hgeometryGiven a three sided range  [x_l,x_r],y! report all points in the range _l,x_r] \times [y,\infty)2. The points are reported in decreasing order of y -coordinate.running time:  O(\log n + k), where k" is the number of reported points. hgeometry%Implementation fo the query function.ghijkghijkNone%&',-.14567=>?@AHMPSUVX_gknr hgeometryReturns the discrete frechet distance between two point sequences using the squared Euclidean distance. In other words, returns the square of the (Euclidean) frechet distance.running time: O((nm)), where n and m# are the lengths of the sequences.s hgeometrydReturns the discrete frechet distance between two point sequences using the given distance measure.running time: O((nm)), where n and mc are the lengths of the sequences (and assuming that a distance calculation takes constant time). hgeometrycompute the discrete frechet distance between the subtrajectories up to the given Loc using dpTable for memoization memoization hgeometryLook up a value in the DP Table hgeometryStoer a value in the DP table hgeometryCandidate previous locationss hgeometrydistance functionrsrs(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk( v hgeometryType used in the closest pair computation. The fields represent the points ordered on increasing y-order and the closest pair (if we know it)x hgeometry+the closest pair and its (squared) distancey hgeometryJClassical divide and conquer algorithm to compute the closest pair among n points.running time: O(n)z hgeometry*Function that does the actual merging work hgeometry4ditch the points on the left that are too low anyway hgeometryEthe squared vertical distance (in case r lies above l) or 0 otherwise hgeometrytry and find a new closest pair with r. If we get to points that are too far above r we stop (since none of those points will be closer to r anyway) hgeometryRGiven some function that decides when to keep things while maintaining some state. hgeometry7returns the minimum element according to some function. hgeometry.Get the distance of a (candidate) closest pairz hgeometry!current closest pair and its dist hgeometrypts on the left hgeometrypts on the rightvwxyzyxvwzaUnsafe%&',-.14567=>?@AHMPSUVX_gk0 hgeometrycCreates a row with zeroes everywhere, except at position i, where the value is the supplied value.(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk hgeometry?a matrix of n rows, each of m columns, storing values of type r hgeometryProduces the Identity Matrix ~ ~Unsafe%&',-.14567=>?@AHMPSUVX_gkh hgeometryIA class representing types that can be transformed using a transformation hgeometry>A type representing a Transformation for d dimensional objects hgeometry'Compose transformations (right to left) hgeometry"Compute the inverse transformation.inverseOf $ translation (Vector2 (10.0) (5.0))~Transformation {_transformationMatrix = Matrix Vector3 [Vector3 [1.0,0.0,-10.0],Vector3 [0.0,1.0,-5.0],Vector3 [0.0,0.0,1.0]]} hgeometryRow in a translation matrix transRow :: forall n r. ( Arity n, Arity (n- 1), ((n - 1) + 1) ~ n , Num r) => Int -> r -> Vector n r transRow i x = set (V.element (Proxy :: Proxy (n-1))) x $ mkRow i 1 hgeometryzGiven three new unit-length basis vectors (u,v,w) that map to (x,y,z), construct the appropriate rotation that does this. hgeometryUSkew transformation that keeps the y-coordinates fixed and shifts the x coordinates.None%&',-.14567=>?@AHMPSUVX_gk hgeometry`Result of a query that asks if something is Inside a g, *on* the boundary of the g, or outside. hgeometry#The boundary of a geometric object. hgeometryJIso for converting between things with a boundary and without its boundarybNone%&',-.14567=>?@AHMPSUVX_gk hgeometry)pre: computes the sign of the determinant(C) Frank Staalssee the LICENSE file Frank StaalsNone!%&',-.145679=>?@AHMPSUVX_gk hgeometryJA line is given by an anchor point and a vector indicating the direction. hgeometryResult of a side test hgeometryResult of a side test hgeometry`Types for which we can compute a supporting line, i.e. a line that contains the thing of type t. hgeometry*A line may be constructed from two points. hgeometryGiven a line l with anchor point p and vector v, get the line perpendicular to l that also goes through p. The resulting line m is oriented such that v points into the left halfplane of m.4perpendicularTo $ Line (Point2 3 4) (Vector2 (-1) 2)%Line (Point2 [3,4]) (Vector2 [-2,-1]) hgeometry.Test if a vector is perpendicular to the line. hgeometrymTest if two lines are identical, meaning; if they have exactly the same anchor point and directional vector. hgeometry#Test if the two lines are parallel.TlineThrough origin (Point2 1 0) `isParallelTo` lineThrough (Point2 1 1) (Point2 2 1)TrueTlineThrough origin (Point2 1 0) `isParallelTo` lineThrough (Point2 1 1) (Point2 2 2)False hgeometryTest if point p lies on line l/origin `onLine` lineThrough origin (Point2 1 0)True5Point2 10 10 `onLine` lineThrough origin (Point2 2 2)True4Point2 10 5 `onLine` lineThrough origin (Point2 2 2)False hgeometry8Specific 2d version of testing if apoint lies on a line. hgeometryGet the point at the given position along line, where 0 corresponds to the anchorPoint of the line, and 1 to the point anchorPoint .+^ directionVector hgeometryGiven point p and a line (Line q v), Get the scalar lambda s.t. p = q + lambda v. If p does not lie on the line this returns a Nothing. hgeometryuGiven point p *on* a line (Line q v), Get the scalar lambda s.t. p = q + lambda v. (So this is an unsafe version of )*pre: the input point p lies on the line l. hgeometry'Squared distance from point p to line l hgeometrybThe squared distance between the point p and the line l, and the point m realizing this distance. hgeometry-Create a line from the linear function ax + b hgeometrygget values a,b s.t. the input line is described by y = ax + b. returns Nothing if the line is vertical hgeometryGiven a point q and a line l, compute to which side of l q lies. For vertical lines the left side of the line is interpeted as below.8Point2 10 10 `onSide` (lineThrough origin $ Point2 10 5)LeftSide;Point2 10 10 `onSide` (lineThrough origin $ Point2 (-10) 5) RightSide%Point2 5 5 `onSide` (verticalLine 10)LeftSide;Point2 5 5 `onSide` (lineThrough origin $ Point2 (-3) (-3))OnLine hgeometry6Test if the query point q lies (strictly) above line l hgeometry#Get the bisector between two points hgeometryVCompares the lines on slope. Vertical lines are considered larger than anything else.B(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 3 3))LTE(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 (-3) 3))GTB(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 0 1))LT hgeometryKThe intersection of two lines is either: NoIntersection, a point or a line.&&(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gkX  hgeometryrPart of a line. The interval is ranged based on the vector of the line l, and s.t.t zero is the anchorPoint of l. hgeometry3Annotate the subRange with the actual ending points hgeometryDforget the extra information stored at the endpoints of the subline. hgeometry?Transform into an subline with a potentially unbounded interval hgeometry?Try to make a potentially unbounded subline into a bounded one. hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r  hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r  hgeometry*Get the endpoints of an unbounded interval        (C) Frank Staalssee the LICENSE file Frank StaalsNone!%&',-./14567=>?@AHMPSUVX_gk  hgeometryCoordinate wize minimum  hgeometryCoordinate wize maximum9 hgeometrybGiven the point with the lowest coordinates and the point with highest coordinates, create a box.: hgeometrygrows the box by x on all sides; hgeometry)Build a d dimensional Box given d ranges.< hgeometryNGiven a center point and a vector specifying the box width's, construct a box.= hgeometryCenter of the box@ hgeometryCheck if a point lies a boxQorigin `inBox` (boundingBoxList' [Point3 1 2 3, Point3 10 20 30] :: Box 3 () Int)FalseZorigin `inBox` (boundingBoxList' [Point3 (-1) (-2) (-3), Point3 10 20 30] :: Box 3 () Int)TrueA hgeometryGet a vector with the extent of the box in each dimension. Note that the resulting vector is 0 indexed whereas one would normally count dimensions starting at zero.Iextent (boundingBoxList' [Point3 1 2 3, Point3 10 20 30] :: Box 3 () Int)`Vector3 [Range (Closed 1) (Closed 10),Range (Closed 2) (Closed 20),Range (Closed 3) (Closed 30)]B hgeometryGet the size of the box (in all dimensions). Note that the resulting vector is 0 indexed whereas one would normally count dimensions starting at zero.>size (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)Vector3 [1,2,3]C hgeometryXGiven a dimension, get the width of the box in that dimension. Dimensions are 1 indexed.LwidthIn (C :: C 1) (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)1LwidthIn (C :: C 3) (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)3D hgeometrySame as C6 but with a runtime int instead of a static dimension.DwidthIn' 1 (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)Just 1DwidthIn' 3 (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)Just 3EwidthIn' 10 (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)NothingH hgeometryOUnsafe version of boundingBoxList, that does not check if the list is non-empty! !"#-.0/1456789:;<=>?@ABCDEFGH!# !"1-.0/879:;<=>?@ABCD6EF45GH(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gk/e X hgeometryLine segments. LineSegments have a start and end point, both of which may contain additional data of type p. We can think of a Line-Segment being defined as\data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p))[ hgeometryHGets the start and end point, but forgetting if they are open or closed.\ hgeometry6Pattern that essentially models the line segment as a:\data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p))] hgeometryTraversal to access the endpoints. Note that this traversal allows you to change more or less everything, even the dimension and the numeric type used, but it preservers if the segment is open or closed._ hgeometry,Directly convert a line into a line segment.` hgeometry'Test if a point lies on a line segment.N(Point2 1 0) `onSegment` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))TrueN(Point2 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))FalseN(Point2 5 0) `onSegment` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))FalseQ(Point2 (-1) 0) `onSegment` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))FalseN(Point2 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (Point2 3 3 :+ ()))TrueVNote that the segments are assumed to be closed. So the end points lie on the segment.N(Point2 2 0) `onSegment` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))TrueHorigin `onSegment` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))True,This function works for arbitrary dimensons.R(Point3 1 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (Point3 3 3 3 :+ ()))TrueR(Point3 1 2 1) `onSegment` (ClosedLineSegment (origin :+ ()) (Point3 3 3 3 :+ ()))Falsea hgeometryNThe left and right end point (or left below right if they have equal x-coords)b hgeometryLength of the line segmentc hgeometryNSquared distance from the point to the Segment s. The same remark as for the d applies here.d hgeometryESquared distance from the point to the Segment s, and the point on s realizing it. Note that if the segment is *open*, the closest point returned may be one of the (open) end points, even though technically the end point does not lie on the segment. (The true closest point then lies arbitrarily close to the end point).e hgeometry,flips the start and end point of the segmentf hgeometryFLinearly interpolate the two endpoints with a value in the range [0,1]Kinterpolate 0.5 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)Point2 [5.0,5.0]Kinterpolate 0.1 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)Point2 [1.0,1.0]Iinterpolate 0 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)Point2 [0.0,0.0]Iinterpolate 1 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)Point2 [10.0,10.0]: XYZ[\]^_`abcdef:X\[ZY]^ _`abcdefNone%&',-.14567=>?@AHMPSUVX_gk4 hgeometry]reports true if there is at least one segment for which this intersection point is interior.O(1)uvxwyz{}|~~z{}|yuvxwNone%&',-.14567=>?@AHMPSUVX_gk9o hgeometry#Compute all intersections (naively)O(n^2) hgeometryHTest if the two segments intersect, and if so add the segment to the map hgeometry"Add s and s' to the map with key p hgeometry(figure out which map to add the point to(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkQ hgeometry1The actual event consists of a point and its type hgeometryType of segment hgeometryCompute all intersectionsO((n+k)\log n), where k is the number of intersections. hgeometry`Computes all intersection points p s.t. p lies in the interior of at least one of the segments.O((n+k)\log n), where k is the number of intersections. hgeometry2Computes the event points for a given line segment hgeometry/Group the segments with the intersection points hgeometry\Group the startpoints such that segments with the same start point correspond to one event. hgeometry4An ordering that is decreasing on y, increasing on x hgeometry4Get the segments that start at the given event point hgeometryYCompare based on the x-coordinate of the intersection with the horizontal line through y hgeometryGiven a y coord and a line segment that intersects the horizontal line through y, compute the x-coordinate of this intersection point.Lnote that we will pretend that the line segment is closed, even if it is not hgeometry!Run the sweep handling all events hgeometryHandle an event point hgeometryjsplit the status structure, extracting the segments that contain p. the result is (before,contains,after) hgeometry`Given a point and the linesegements that contain it. Create a piece of status structure for it. hgeometry#Get the right endpoint of a segment hgeometryTest if a segment ends at p hgeometryFind all events None%&',-.14567=>?@AHMPSUVX_gkY  hgeometryA Quadrant data type hgeometryGet the corners of a rectangle, the order is: (TopLeft, TopRight, BottomRight, BottomLeft). The extra values in the Top points are taken from the Top point, the extra values in the Bottom points are taken from the Bottom point hgeometry*Gets the corners in a particular direction!None%&',-.14567=>?@AHMPSUVX_gkZh "None%&',-.14567=>?@AHMPSUVX_gkh hgeometryThe four sides of a rectangle hgeometryCConstructs a Sides value that indicates the appropriate direction. hgeometryOriented from *left to right* hgeometry-The right side, oriented from *bottom* to top hgeometryThe sides of the rectangle, in order (Top, Right, Bottom, Left). The sides themselves are also oriented in clockwise order. If, you want them in the same order as the functions , , , and , use  instead. hgeometryYThe sides of the rectangle. The order of the segments is (Top, Right, Bottom, Left). Note that the segments themselves, are oriented as described by the functions topSide, bottomSide, leftSide, rightSide (basically: from left to right, and from bottom to top). If you want the segments oriented along the boundary of the rectangle, use the  function instead.  #(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.145679=>?@AHMPSUVX_gkj6 !"#-./01456789:;<=>?@ABCDEFGH$None%&',-.14567=>?@AHMPSUVX_gkj hgeometry.A Cell corresponding to a node in the QuadTree hgeometry+side lengths will be 2^i for some integer i hgeometry1Computes a cell that contains the given rectangle hgeometrySides are open hgeometry*Partitions the points into quadrants. See  for the precise rules. hgeometryComputes the quadrant of the cell corresponding to the current point. Note that we decide the quadrant solely based on the midpoint. If the query point lies outside the cell, it is still assigned a quadrant.9The northEast quadrants includes its bottom and left side9The southEast quadrant includes its left side9The northWest quadrant includes its bottom side:The southWest quadrants does not include any of its sides.'quadrantOf (Point2 9 9) (Cell 4 origin) NorthEast'quadrantOf (Point2 8 9) (Cell 4 origin) NorthEast'quadrantOf (Point2 8 8) (Cell 4 origin) NorthEast'quadrantOf (Point2 8 7) (Cell 4 origin) SouthEast'quadrantOf (Point2 4 7) (Cell 4 origin) SouthWest(quadrantOf (Point2 4 10) (Cell 4 origin) NorthWest(quadrantOf (Point2 4 40) (Cell 4 origin) NorthEast(quadrantOf (Point2 4 40) (Cell 4 origin) NorthWest hgeometry3Given two cells c and me, compute on which side of me the cell c is.!pre: c and me are non-overlapping%None%&',-.14567=>?@AHMPSUVX_gk_ hgeometryDData Type to Decide if we should continue splitting the current cell hgeometry/Transformer that limits the depth of a splitter  hgeometrywA splitter is a function that determines weather or not we should the given cell corresponding to the given input (i).  hgeometry/Split only when the Cell-width is at least wMin  hgeometry7smallest allowed width of a cell (i.e. width of a leaf)        &None%&',-.14567=>?@AHMPSUVX_gk?   hgeometryWOur cells use Rational numbers as their numeric type type CellR = Cell (RealNumber 10),The Actual Tree type representing a quadTree hgeometryFold on the Tree type. hgeometry+Produce a list of all leaves of a quad tree hgeometryConverts into a RoseTree hgeometry#Computes the height of the quadtree hgeometryBuilds a QuadTree hgeometry-Annotate the tree with its corresponing cells hgeometry'Build a QuadtTree from a set of points.2pre: the points lie inside the initial given cell.running time: O(nh), where n is the number of points and h) is the height of the resulting quadTree. hgeometry2The function that can be used to build a quadTree     'None%&',-.14567=>?@AHMPSUVX_gk ! hgeometryQuadTree on the starting cell6 hgeometryfGiven a starting cell, a Tree builder, and some input required by the builder, constructs a quadTree.7 hgeometry8The Equivalent of Tree.build for constructing a QuadTree8 hgeometry'Build a QuadtTree from a set of points.2pre: the points lie inside the initial given cell.running time: O(nh), where n is the number of points and h) is the height of the resulting quadTree.: hgeometry:Locates the cell containing the given point, if it exists.running time: O(h), where h is the height of the quadTree> hgeometry&Interpret an ordering result as a Sign@ hgeometryUSplitter that determines if we should split a cell based on the sign of the corners.B hgeometry9Constructs an empty/complete tree from the starting width@ hgeometryThe function we are evaluatingA hgeometrythe zero value!"$#+-.,/0123456789:;<=>?@AB!"$#1023456789:;</=+-.,>?@AB(None %&',-.14567=>?@AHMPSUVX_gku F hgeometry*A Poly line in R^d has at least 2 verticesK hgeometryNBuilds a Polyline from a list of points, if there are sufficiently many pointsL hgeometry0pre: The input list contains at least two pointsM hgeometry`pre: The input list contains at least two points. All extra vields are initialized with mempty.N hgeometry'We consider the line-segment as closed.O hgeometry@Convert to a closed line segment by taking the first two points.P hgeometry\Stricter version of asLineSegment that fails if the Polyline contains more than two points.Q hgeometry/Computes the edges, as linesegments, of an LSeqR hgeometry=Linearly interpolate the polyline with a value in the range [0,n-1], where n+ is the number of vertices of the polyline.running time:  O(\log n)interpolatePoly 0.5 myPolyLinePoint2 [5.0,5.0]interpolatePoly 1.5 myPolyLinePoint2 [10.0,15.0] FGHJKLMNOPQR FGHJKLMNOPQR)(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@ADHMPSUVX_gkd hgeometry*Lines are transformable, via line segments&*None%&',-.14567=>?@AHMPSUVX_gkq hgeometryMThe two bounding lines of the slab, first the lower one, then the higher one:t hgeometry0Smart consturctor for creating a horizontal slabu hgeometry.Smart consturctor for creating a vertical slab efghjiprqstu hjiefgstuprq+None!%&',-.145679=>?@AHMPSUVX_gk hgeometryHyperplanes embedded in a d dimensional space. hgeometrymTypes for which we can compute a supporting hyperplane, i.e. a hyperplane that contains the thing of type t. hgeometryProduces a plane. If r lies counter clockwise of q w.r.t. p then the normal vector of the resulting plane is pointing "upwards".0from3Points origin (Point3 1 0 0) (Point3 0 1 0)DHyperPlane {_inPlane = Point3 [0,0,0], _normalVec = Vector3 [0,0,1]} hgeometry%Convert between lines and hyperplanes hgeometryGiven * a plane, * a unit vector in the plane that will represent the y-axis (i.e. the "view up" vector), and * a point in the plane,computes the plane coordinates of the given point, using the inPlane point as the origin, the normal vector of the plane as the unit vector in the "z-direction" and the view up vector as the y-axis.TplaneCoordinatesWith (Plane origin (Vector3 0 0 1)) (Vector3 0 1 0) (Point3 10 10 0)Point2 [10.0,10.0],None!%&',-.145679=>?@AHMPSUVX_gkm hgeometryd-dimensional Half-Lines hgeometry#Test if a point lies on a half-line hgeometryTransform a LineSegment into a half-line, by forgetting the second endpoint. Note that this also forgets about if the starting point was open or closed.  -(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gkۨ hgeometryA Halfspace in d| dimensions. Note that the intended side of the halfspace is already indicated by the normal vector of the bounding plane. hgeometry6Get the halfplane left of a line (i.e. "above") a lineleftOf $ horizontalLine 4]HalfSpace {_boundingPlane = HyperPlane {_inPlane = Point2 [0,4], _normalVec = Vector2 [0,1]}} hgeometry7Get the halfplane right of a line (i.e. "below") a linerightOf $ horizontalLine 4^HalfSpace {_boundingPlane = HyperPlane {_inPlane = Point2 [0,4], _normalVec = Vector2 [0,-1]}} hgeometry#Test if a point lies in a halfspace  .None%&',-.14567=>?@AHMPSUVX_gkX hgeometry1Maps a line point (px,py) to a line (y=px*x - py) hgeometryZReturns Nothing if the input line is vertical Maps a line l: y = ax + b to a point (a,-b) hgeometry#Pre: the input line is not vertical/None%&',-.14567=>?@AHMPSUVX_gk hgeometry1Expects the input to be a set, i.e. no duplicatesrunning time:  O(n \log n) hgeometryNub by sorting first hgeometrySearches in a KDTreerunning time: O(n^{(d-1)/d} + k) hgeometryrunning time: O(n)0None %&',-.14567=>?@AHMPSUVX_gk  hgeometry/Datatype representing a Bezier curve of degree n in d-dimensional space. hgeometryCubic Bezier Spline hgeometryQuadratic Bezier Spline hgeometry=Constructs the Bezier Spline from a given sequence of points. hgeometry1Evaluate a BezierSpline curve at time t in [0, 1]pre:  t \in [0,1] hgeometryIRestrict a Bezier curve to th,e piece between parameters t < u in [0, 1]. hgeometry9Split a Bezier curve at time t in [0, 1] into two pieces. hgeometry;Approximate Bezier curve by Polyline with given resolution. hgeometryGiven a point on (or close to) a Bezier curve, return the corresponding parameter value. (For points far away from the curve, the function will return the parameter value of an approximate locally closest point to the input point.) hgeometry2Snap a point close to a Bezier curve to the curve.  1(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gk  hgeometryA d-dimensional ball. hgeometry%Spheres, i.e. the boundary of a ball. hgeometry<Given the center and the squared radius, constructs a circle  hgeometry:Given the center and the squared radius, constructs a disk  hgeometry&A lens to get/set the radius of a Ball hgeometry?Given two points on the diameter of the ball, construct a ball. hgeometryFConstruct a ball given the center point and a point p on the boundary. hgeometry1A d dimensional unit ball centered at the origin. hgeometry+Test if a point lies strictly inside a ball&(Point2 0.5 0.0) `insideBall` unitBallTrue"(Point2 1 0) `insideBall` unitBallFalse"(Point2 2 0) `insideBall` unitBallFalse hgeometry&Test if a point lies in or on the ball hgeometry/Test if a point lies on the boundary of a ball.(Point2 1 0) `onBall` unitBallTrue (Point3 1 1 0) `onBall` unitBallFalse hgeometry hgeometryJIso for converting between Disks and Circles, i.e. forgetting the boundary hgeometrytGiven three points, get the disk through the three points. If the three input points are colinear we return Nothing1disk (Point2 0 10) (Point2 10 0) (Point2 (-10) 0)FJust (Ball {_center = Point2 [0.0,0.0] :+ (), _squaredRadius = 100.0}) hgeometry2Creates a circle from three points on the boundary hgeometrydA line segment may not intersect a circle, touch it, or intersect it properly in one or two points. hgeometry2No intersection, one touching point, or two points          2None%&',-.14567=>?@AHMPSUVX_gkp & hgeometry Triangles in d-dimensional space.( hgeometryEconvenience function to construct a triangle without associated data.+ hgeometryCompute the area of a triangle, hgeometry2*the area of a triangle.- hgeometry9Checks if the triangle is degenerate, i.e. has zero area.. hgeometryhget the inscribed disk. Returns Nothing if the triangle is degenerate, i.e. if the points are colinear./ hgeometry[Given a point q and a triangle, q inside the triangle, get the baricentric cordinates of q0 hgeometryGiven a vector of barricentric coordinates and a triangle, get the corresponding point in the same coordinate sytsem as the vertices of the triangle.1 hgeometryQTests if a point lies inside a triangle, on its boundary, or outside the triangle2 hgeometry<Test if a point lies inside or on the boundary of a triangle &'()*+,-./012 &')(*+,-./012c(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkklC hgeometryEither a simple or multipolygonI hgeometryOWe distinguish between simple polygons (without holes) and Polygons with holes.L hgeometry Prism to test if we are a simple polygonM hgeometry Prism to test if we are a Multi polygonQ hgeometry,Access the i^th vertex on the outer boundaryS hgeometryGet all holes in a polygonT hgeometryXThe vertices in the polygon. No guarantees are given on the order in which they appear!U hgeometry9Creates a simple polygon from the given list of vertices.3pre: the input list constains no repeated vertices.V hgeometryKThe edges along the outer boundary of the polygon. The edges are half open.running time: O(n)W hgeometryLists all edges. The edges on the outer boundary are given before the ones on the holes. However, no other guarantees are given on the order.running time: O(n)X hgeometryPairs every vertex with its incident edges. The first one is its predecessor edge, the second one its successor edge (in terms of the ordering along the boundary).<mapM_ print . polygonVertices $ withIncidentEdges simplePolyPoint2 [0,0] :+ V2 LineSegment (Closed (Point2 [1,11] :+ ())) (Closed (Point2 [0,0] :+ ())) LineSegment (Closed (Point2 [0,0] :+ ())) (Closed (Point2 [10,0] :+ ()))Point2 [10,0] :+ V2 LineSegment (Closed (Point2 [0,0] :+ ())) (Closed (Point2 [10,0] :+ ())) LineSegment (Closed (Point2 [10,0] :+ ())) (Closed (Point2 [10,10] :+ ()))Point2 [10,10] :+ V2 LineSegment (Closed (Point2 [10,0] :+ ())) (Closed (Point2 [10,10] :+ ())) LineSegment (Closed (Point2 [10,10] :+ ())) (Closed (Point2 [5,15] :+ ()))Point2 [5,15] :+ V2 LineSegment (Closed (Point2 [10,10] :+ ())) (Closed (Point2 [5,15] :+ ())) LineSegment (Closed (Point2 [5,15] :+ ())) (Closed (Point2 [1,11] :+ ()))Point2 [1,11] :+ V2 LineSegment (Closed (Point2 [5,15] :+ ())) (Closed (Point2 [1,11] :+ ())) LineSegment (Closed (Point2 [1,11] :+ ())) (Closed (Point2 [0,0] :+ ())) hgeometryUGiven the vertices of the polygon. Produce a list of edges. The edges are half-open.Y hgeometryATest if q lies on the boundary of the polygon. Running time: O(n)"Point2 1 1 `onBoundary` simplePolyFalse"Point2 0 0 `onBoundary` simplePolyTrue#Point2 10 0 `onBoundary` simplePolyTrue#Point2 5 13 `onBoundary` simplePolyFalse#Point2 5 10 `onBoundary` simplePolyFalse#Point2 10 5 `onBoundary` simplePolyTrue#Point2 20 5 `onBoundary` simplePolyFalseTODO: testcases multipolygonZ hgeometryhCheck if a point lies inside a polygon, on the boundary, or outside of the polygon. Running time: O(n).!Point2 1 1 `inPolygon` simplePolyInside!Point2 0 0 `inPolygon` simplePoly OnBoundary"Point2 10 0 `inPolygon` simplePoly OnBoundary"Point2 5 13 `inPolygon` simplePolyInside"Point2 5 10 `inPolygon` simplePolyInside"Point2 10 5 `inPolygon` simplePoly OnBoundary"Point2 20 5 `inPolygon` simplePolyOutsideUTODO: Add some testcases with multiPolygons TODO: Add some more onBoundary testcases[ hgeometry1Test if a point lies strictly inside the polgyon.\ hgeometryCompute the area of a polygon] hgeometryCompute the signed area of a simple polygon. The the vertices are in clockwise order, the signed area will be negative, if the verices are given in counter clockwise order, the area will be positive.^ hgeometry)Compute the centroid of a simple polygon._ hgeometry)Pick a point that is inside the polygon.g(note: if the polygon is degenerate; i.e. has <3 vertices, we report a vertex of the polygon instead.)&pre: the polygon is given in CCW orderrunning time: O(n)` hgeometry!Test if the polygon is a trianglerunning time: O(1)a hgeometryFind a diagonal of the polygon.&pre: the polygon is given in CCW orderrunning time: O(n)b hgeometryVTest if the outer boundary of the polygon is in clockwise or counter clockwise order.running time: O(n)c hgeometryMake sure that every edge has the polygon's interior on its right, by orienting the outer boundary into clockwise order, and the inner borders (i.e. any holes, if they exist) into counter-clockwise order.running time: O(n)? | Orient the outer boundary of the polygon to clockwise orderd hgeometryNOrient the outer boundary into clockwise order. Leaves any holes as they are.e hgeometryMake sure that every edge has the polygon's interior on its left, by orienting the outer boundary into counter-clockwise order, and the inner borders (i.e. any holes, if they exist) into clockwise order.running time: O(n)f hgeometryVOrient the outer boundary into counter-clockwise order. Leaves any holes as they are.h hgeometryDConvert a Polygon to a simple polygon by forgetting about any holes.i hgeometryassigns unique integer numbers to all vertices. Numbers start from 0, and are increasing along the outer boundary. The vertices of holes will be numbered last, in the same order.numberVertices simplePolySimplePolygon (CSeq [Point2 [0,0] :+ SP 0 (),Point2 [10,0] :+ SP 1 (),Point2 [10,10] :+ SP 2 (),Point2 [5,15] :+ SP 3 (),Point2 [1,11] :+ SP 4 ()]) hgeometry)Polygons are per definition 2 dimensional'CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghid(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkqj hgeometry(Comparison that compares which point is larger) in the direction given by the vector u.k hgeometryCFinds the extreme points, minimum and maximum, in a given directionrunning time: O(n)jk4(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkl hgeometry'Data Type representing a convex polygons hgeometryCFinds the extreme points, minimum and maximum, in a given direction*pre: The input polygon is strictly convex.running time:  O(\log n)t hgeometryBFinds the extreme maximum point in the given direction. Based on /http://geomalgorithms.com/a14-_extreme_pts.html*pre: The input polygon is strictly convex.running time:  O(\log^2 n)w hgeometryRotating Right  - rotate clockwise-Merging two convex hulls, based on the paper:Two Algorithms for Constructing a Delaunay Triangulation Lee and Schachter International Journal of Computer and Information Sciences, Vol 9, No. 3, 1980O: (combined hull, lower tangent that was added, upper tangent thtat was added)x hgeometry-Compute the lower tangent of the two polgyonspre: - polygons lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line separating the two polygons. - The vertices of the polygons are given in clockwise orderRRunning time: O(n+m), where n and m are the sizes of the two polygons respectivelyy hgeometry<Compute the lower tangent of the two convex chains lp and rp[pre: - the chains lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line having lp on the left and rp on the right. - The vertices in the left-chain are given in clockwise order, (right to left) - The vertices in the right chain are given in counterclockwise order (left-to-right)The result returned is the two endpoints l and r of the tangents, and the remainders lc and rc of the chains (i.e.) such that the lower hull of both chains is: (reverse lc) ++ [l,h] ++ rcRunning time: O(n+m)=, where n and m are the sizes of the two chains respectivelyz hgeometry-Compute the upper tangent of the two polgyonspre: - polygons lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line separating the two polygons. - The vertices of the polygons are given in clockwise orderRRunning time: O(n+m), where n and m are the sizes of the two polygons respectively{ hgeometry<Compute the upper tangent of the two convex chains lp and rp[pre: - the chains lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line having lp on the left and rp on the right. - The vertices in the left-chain are given in clockwise order, (right to left) - The vertices in the right chain are given in counterclockwise order (left-to-right)The result returned is the two endpoints l and r of the tangents, and the remainders lc and rc of the chains (i.e.) such that the upper hull of both chains is: (reverse lc) ++ [l,h] ++ rcRunning time: O(n+m)=, where n and m are the sizes of the two chains respectively| hgeometry]Computes the Minkowski sum of the two input polygons with $n$ and $m$ vertices respectively.%pre: input polygons are in CCW order.running time: O(n+m). hgeometryERotate to the rightmost point (rightmost and topmost in case of ties) hgeometry=Rotate to the leftmost point (and bottommost in case of ties)} hgeometry=Rotate to the bottommost point (and leftmost in case of ties) hgeometry.Helper to get the vertices of a convex polygon hgeometry)Polygons are per definition 2 dimensionallmnrstuvwxyz{|}lmnrwxyz{stuv|}5None%&',-.14567=>?@AHMPSUVX_gk hgeometry$A typre representing planar ellipses hgeometry$Ellipse representing the unit circle hgeometry'Converting between ellipses and circles6(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gk hgeometry$Data that we store in the split tree7(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk hgeometryCST monad with access to the vector storign the level of the points. hgeometryConstruct a split treerunning time:  O(n \log n) hgeometry5Given a split tree, generate the Well separated pairsrunning time: O(s^d n) hgeometryKGiven the points, sorted in every dimension, recursively build a split treeThe algorithm works in rounds. Each round takes O(n) time, and halves the number of points. Thus, the total running time is O(n log n).The algorithm essentially builds a path in the split tree; at every node on the path that we construct, we split the point set into two sets (L,R) according to the longest side of the bounding box.The smaller set is "assigned" to the current node and set asside. We continue to build the path with the larger set until the total number of items remaining is less than n/2.`To start the next round, each node on the path needs to have the points assigned to that node, sorted in each dimension (i.e. the Vector (PointSeq))'s. Since we have the level assignment, we can compute these lists by traversing each original input list (i.e. one for every dimension) once, and partition the points based on their level assignment. hgeometry2Assign the points to their the correct class. The $ class is considered the last class hgeometry2Assign the points to their the correct class. The $ class is considered the last class hgeometryGiven a sequence of points, whose index is increasing in the first dimension, i.e. if idx p < idx q, then p[0] < q[0]. Reindex the points so that they again have an index in the range [0,..,n'], where n' is the new number of points.Xrunning time: O(n' * d) (more or less; we are actually using an intmap for the lookups)alternatively: I can unsafe freeze and thaw an existing vector to pass it along to use as mapping. Except then I would have to force the evaluation order, i.e. we cannot be in ( for two of the nodes at the same time.0so, basically, run reIndex points in ST as well. hgeometryAssigns the points to a level. Returns the list of levels used. The first level in the list is the level assigned to the rest of the nodes. Their level is actually still set to Nothing in the underlying array. hgeometry9Remove already assigned pts from the ends of all vectors. hgeometryAssign level l to point p hgeometryGet the level of a point hgeometry5Test if the point already has a level assigned to it. hgeometry1Remove allready assigned points from the sequencepre: there are points remaining hgeometryGiven the points, ordered by their j^th coordinate, split the point set into a "left" and a "right" half, i.e. the points whose j^th coordinate is at most the given mid point m, and the points whose j^th coordinate is larger than m.,We return a pair (Largest set, Smallest set)fi ndAndCompact works by simultaneously traversing the points from left to right, and from right to left. As soon as we find a point crossing the mid point we stop and return. Thus, in principle this takes only O(|Smallest set|) time.running time: O(|Smallest set|) + R, where R is the number of *old* points (i.e. points that should have been removed) in the list. hgeometry*Find the widest dimension of the point set3pre: points are sorted according to their dimension hgeometry]get the extends of the set of points in every dimension, i.e. the left and right boundaries.3pre: points are sorted according to their dimension hgeometry4Test if the two sets are well separated with param s hgeometry1Test if the two boxes are sufficiently far appart hgeometry)Computes the maximum width of a splitTree hgeometryComputes! the bounding box of a split tree hgeometryTurn a traversal into lens hgeometrynumber of classes hgeometrylevel assignment hgeometry input points hgeometry"Number of items we need to collect hgeometry#Number of items we collected so far hgeometrynext level to use hgeometryLevels used so far hgeometryWthe dimension we are in, i.e. so that we know which coordinate of the point to compare hgeometry the mid point hgeometryseparation factoreNone%&',-.14567=>?@AHMPSUVX_gk  hgeometryhA dimension d has support for SoS when we can: compute a dterminant of a d+1 by d+1 dimensional matrix. hgeometryGiven a query point q, and a vector of d points defining a hyperplane test if q lies above or below the hyperplane. Each point is assumed to have an unique index of type i that can be used to disambiguate it in case of degeneracies.some 1D examples:2sideTest (Point1 0 :+ 0) (Vector1 $ Point1 2 :+ 1)Negative3sideTest (Point1 10 :+ 0) (Vector1 $ Point1 2 :+ 1)Positive2sideTest (Point1 2 :+ 0) (Vector1 $ Point1 2 :+ 1)Positive2sideTest (Point1 2 :+ 3) (Vector1 $ Point1 2 :+ 1)Negativesome 2D examples:HsideTest (Point2 1 2 :+ 0) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)PositiveKsideTest (Point2 1 (-2) :+ 0) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)NegativeHsideTest (Point2 1 1 :+ 0) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)PositiveIsideTest (Point2 1 1 :+ 10) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)NegativeIsideTest (Point2 1 1 :+ 10) $ Vector2 (Point2 0 0 :+ 3) (Point2 2 2 :+ 1)Negative hgeometryuGiven an input point, transform its number type to include symbolic $varepsilon$ expressions so that we can use SoS. hgeometrymGiven a point q and a vector of d points defining a hyperplane, test on which side of the hyperplane q lies.!TODO: Specify what the sign means hgeometryGiven a vector of points, tests if the point encoded in the first row is above/below the hyperplane defined by the remaining points (rows). hgeometryGiven a point produces the vector/row corresponding to this point in a homogeneous matrix represetnation. I.e. we add a 1 as an additonal column at the end.fNone%&',-.14567=>?@AHMPSUVX_gkD  hgeometryTGiven three points p q and r determine the orientation when going from p to r via q.     gNone%&',-.14567=>?@AHMPSUVX_gk hgeometry(Indxec type that can disambiguate points hgeometry*a P is a 'read only' point in d dimensionshNone%&',-.14567=>?@AHMPSUVX_gk hgeometry The actual implementation of SoS(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk PQRST PRQST8None%&',-.14567=>?@AHMPSUVX_gk!d hgeometryLine simplification with the well-known Douglas Peucker alogrithm. Given a distance value eps adn a polyline pl, constructs a simplification of pl (i.e. with vertices from pl) s.t. all other vertices are within dist eps to the original polyline.5Running time: O(n^2) worst case, O(n log n) expected. hgeometry;Concatenate the two polylines, dropping their shared vertex hgeometryJSplit the polyline at the given vertex. Both polylines contain this vertex hgeometryGiven a sequence of points, find the index of the point that has the Furthest distance to the LineSegment. The result is the index of the point and this distance.9(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gk$ hgeometry7Data type representing the solution to a linear program  :(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkT hgeometryState during the LP algo hgeometrySolve a linear program hgeometryPSolves a bounded linear program in 2d. Returns Nothing if there is no solution.pre: The linear program is bounded, meaning that *the first two constraints* m1,m2 make sure th the there is no arbitrarily large/good solution. I..e. these halfspaces bound the solution in the c direction.(note that if there is only one constraint, m1, the assumption that the LP is bounded means that the contraint must be perpendicular to the objective direction. Hence, any point on the bounding plane is a solution, and they are all equally good.)O(n) expected time hgeometry&Solves a bounded linear program (like ) assuming that the first two constraints [m1,m2] make sure the solutions is bounded, and the other constraints already have been shuffled. hgeometry(What we do when we get a new halfspace h hgeometrycollect all intersecting halflines on the boundary l of h. If we return a Nothing there is no solution. Just [] indicates that somehow this halfspace h is contained in all other halfspaces. hgeometrySGiven a vector v and two points a and b, determine which is smaller in direction v. hgeometrymComputes the common intersection of a nonempty list of halfines that are all colinear with the given line l.We return either the two halflines that prove that there is no counter example or we return one or two points that form form the boundary points of the range in which all halflines intersect. hgeometryQmaximum of a list using a given comparison ; if the list is empty returns Nothing hgeometry8One dimensional linear programming on lines embedded in  \mathbb{R}^d.Given an objective vector c, a line l, and a collection of half-lines hls that are all sublines of l (i.e. halfspaces *on* l), compute if there is a point inside all these halflines. If so, we actually return the one that maximizes c.running time: O(n) hgeometryLet l be the boundary of h, and assume that we know that the new point in the common intersection must lie on h, try to find this point. In partiuclar, we find the  point in the s^.direction vector. The funtion returns Nothing if no such point exists, i.e. if there is no point on l that is contained in all halfspaces..Note that this is essentially one dinsional LP hgeometryQAssumes that the first two constraints somehow bound the solution in direction c. hgeometryLet n(h)4 denote the normal of the line bounding a halfspace h.5This function tries to Find an "unbounded direction" d. If such a direction di exits the LP is unbounded, and we can produce evidence of this in the form of a half-line in direction d..More formally, we are looking for a direction d so that -  c \cdot d > 0 , and - d \cdot n(h) \geq 0, wherefor every half space h. hgeometryqEither finds an unbounded Haflline, or evidence the two halfspaces that provide evidence that no solution exists3(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkYZ hgeometryTest if a Simple polygon is star-shaped. Returns a point in the kernel (i.e. from which the entire polygon is visible), if it exists.O(n) expected time*CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijk*IJKFGHLMEDCUTWNVQROPSZ[Y\]^_`befcdgaXihkji(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk\ 45:9876>=<;?@ABCDEFGHONMLKJIfg     XYZ[\]^_`abcdefFGHJLMNOPQRCDEFGHIJKLMNOPQRSTVWXYZ[\]^_`abcdefghijkn45:9876>=<;?@ABCDEFGHONMLKJIfgFGHJLMNOPQRCDEFGHIJKLMNOPQRSTVWXYZ[\]^_`abcdefghijk;(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkg hgeometryeThe result of a smallest enclosing disk computation: The smallest ball and the points defining it hgeometryList of two or three elements     <(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkns  hgeometryHorrible O(n^4) implementation that simply tries all disks, checks if they enclose all points, and takes the largest one. Basically, this is only useful to check correctness of the other algorithm(s) hgeometryBGiven a list of canidate enclosing disks, report the smallest one. hgeometry#check if a disk encloses all points  =(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkw hgeometryoCompute the smallest enclosing disk of a set of points, implemented using randomized incremental construction.'pre: the input has at least two points.running time: expected O(n) time, where n is the number of input points. hgeometrySmallest enclosing disk. hgeometry6Smallest enclosing disk, given that p should be on it. hgeometry;Smallest enclosing disk, given that p and q should be on itrunning time: O(n) hgeometryConstructs the initial  from two points>None%&',-.14567=>?@AHMPSUVX_gk} hgeometryBComputes the Euclidean diametral pair by naively trying all pairs.running time: O(n^2) hgeometrymGiven a distance function and a list of points pts, computes the diametral pair by naively trying all pairs.running time: O(n^2)?None%&',-.14567=>?@AHMPSUVX_gk~ hgeometry O(n \log n) hgeometry O(n \log n)@None%&',-.14567=>?@AHMPSUVX_gks hgeometryOConvexHull using Quickhull. The resulting polygon is given in clockwise order.running time: O(n^2) hgeometry2Finds the leftmost and rightmost point in the list  hgeometryinclude neigher left or rightANone%&',-.14567=>?@AHMPSUVX_gk!  hgeometry O(n \log n)W time ConvexHull using Graham-Scan. The resulting polygon is given in clockwise order. hgeometryDComputes the upper hull. The upper hull is given from left to right.Specifically. A pair of points defines an edge of the upper hull iff all other points are strictly to the right of its supporting line.INote that this definition implies that the segment may be vertical. Use ( if such an edge should not be reported.running time:  O(n\log n) hgeometryIComputes the upper hull, making sure that there are no vertical segments.*The upper hull is given from left to right! hgeometry:Helper function to remove vertical segments from the hull.UTests if the first two points are on a vertical line, if so removes the first point. hgeometryDComputes the upper hull. The upper hull is given from left to right.Specifically. A pair of points defines an edge of the lower hull iff all other points are strictly to the left of its supporting line.INote that this definition implies that the segment may be vertical. Use ( if such an edge should not be reported.running time:  O(n\log n) hgeometryComputes the lower hull, making sure there are no vertical segments. (Note that the only such segment could be the first segment)." hgeometrygHelper function so that that can compute both the upper or the lower hull, depending on the function f hgeometryGiven a sequence of points that is sorted on increasing x-coordinate and decreasing y-coordinate, computes the upper hull, in *right to left order*.Specifically. A pair of points defines an edge of the upper hull iff all other points are strictly to the right of its supporting line.Note that In constrast to the ; function, the result is returned *from right to left* !!!running time: O(n). hgeometryOComputes the upper hull from a sorted input. Removes the last vertical segment.running time: O(n).# hgeometry0Precondition: The list of input points is sortedBNone%&',-.14567=>?@AHMPSUVX_gk+" hgeometry{Given a list of non-vertical lines, computes the lower envelope using duality. The lines are given in left to right order. O(n\log n)# hgeometryGiven a list of non-vertical lines, computes the lower envelope by computing the upper convex hull. It uses the given algorithm to do so@running time: O(time required by the given upper hull algorithm)$ hgeometry=Computes the vertices of the envelope, in left to right order% hgeometryrGiven two non-parallel lines, compute the intersection point and return the pair of a's associated with the lines !"#$%!" #$%C(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gki& hgeometry O(n \log n)^ time ConvexHull using divide and conquer. The resulting polygon is given in clockwise order.' hgeometry O(n \log n){ time LowerHull using divide and conquer. The resulting Hull is given from left to right, i.e. in counter clockwise order.( hgeometry O(n \log n)s time UpperHull using divide and conquer. The resulting Hull is given from left to right, i.e. in clockwise order.$ hgeometry.The function that does the actual merging part&'(&('D(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkΟ- hgeometry6Given a set of red points and a set of blue points in  \mathbb{R}^2x finds a separating line (if it exists). The result is non-strict in the sense that there may be points *on* the line.running time: O(n) expected time, where n is the total number of points.. hgeometry6Given a set of red points and a set of blue points in  \mathbb{R}^2 finds a separating line (if it exists) that has all red points *right* (or on) the line, and all blue points left (or on) the line.running time: O(n) expected time, where n is the total number of points./ hgeometrygiven a red and blue point that are *NOT* vertically alligned, and all red and all blue points, try to find a non-vertical separating line.running time: O(n) expected time, where n is the total number of points.0 hgeometry9Computes a strict vertical separating line, if one exists1 hgeometrypTest if there is a vertical separating line that has all red points to its right (or on it) and all blue points to its left (or on it). This function also returns the two extremal points; in case a line is returned, the line actually goes through the blue (second) point, if there is no line, this pair provides evidence that there is no vertical separating line.8The line we return actually goes through one blue point.2 hgeometry<Get the the leftmost red point and the rightmost blue point./ hgeometry red point r hgeometrya blue point b-./012-./012ENone%&',-.14567=>?@AHMPSUVX_gkR4 hgeometry7Computes the lower hull without its vertical triangles.[pre: The points are in general position. In particular, no four points should be coplanar.running time: O(n^4)5 hgeometryGenerates a set of triangles to be used to construct a complete convex hull. In particular, it may contain vertical triangles.[pre: The points are in general position. In particular, no four points should be coplanar.running time: O(n^4)6 hgeometryTests if this is a valid triangle for the lower envelope. That is, if all point lie above the plane through these points. Returns a Maybe; if the result is a Nothing the triangle is valid, if not it returns a counter example.Ilet t = (Triangle (ext origin) (ext $ Point3 1 0 0) (ext $ Point3 0 1 0))&isValidTriangle t [ext $ Point3 5 5 0]NothingIlet t = (Triangle (ext origin) (ext $ Point3 1 0 0) (ext $ Point3 0 1 0))*isValidTriangle t [ext $ Point3 5 5 (-10)]Just (Point3 [5,5,-10] :+ ())7 hgeometry*Computes the halfspace above the triangle.VupperHalfSpaceOf (Triangle (ext $ origin) (ext $ Point3 10 0 0) (ext $ Point3 0 10 0))cHalfSpace {_boundingPlane = HyperPlane {_inPlane = Point3 [0,0,0], _normalVec = Vector3 [0,0,100]}}3456734567FNone%&',-.14567=>?@AHMPSUVX_gk 8 hgeometry]Compute the convexhull using JarvisMarch. The resulting polygon is given in clockwise order.running time: O(nh), where n$ is the number of input points and h is the complexity of the hull.: hgeometry=Upepr hull from left to right, without any vertical segments.; hgeometryVComputes the lower hull, from left to right. Includes vertical segments at the start.running time: O(nh), where h is the complexity of the hull.< hgeometryFJarvis March to compute the lower hull, without any vertical segments.running time: O(nh), where h is the complexity of the hull.= hgeometryjFind the next point in counter clockwise order, i.e. the point with minimum slope w.r.t. the given point.> hgeometrybFind the next point in clockwise order, i.e. the point with maximum slope w.r.t. the given point.% hgeometry2Removes the topmost vertical points, if they exist& hgeometry_Foldr, but start by applying some function on the rightmost element to get the starting value.' hgeometryextracts all minima from the list. The result consists of the list of minima, and all remaining points. Both lists are returned in the order in which they occur in the input.1extractMinimaBy compare [1,2,3,0,1,2,3,0,1,2,0,2][0,0,0] :+ [2,3,1,2,3,1,2,1,2]89:;<=>89:;<=>G(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk@ hgeometry^Naive algorithm to compute the closest pair according to the (squared) Euclidean distance in dU dimensions. Note that we need at least two elements for there to be a closest pair.running time: O(dn^2) time.A hgeometryNaive algorithm to compute the closest pair of points (and the distance realized by those points) given a distance function. Note that we need at least two elements for there to be a closest pair.running time:  O(T(d)n^2), where T(d)F is the time required to evaluate the distance between two points in  \mathbb{R}^d.( hgeometryxProduce all lists from a vec of elements. Since the Vec contains at least two elements, the resulting list is non-empty?@A@A?(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkB hgeometryHA vertex, represented by an id, location, its adjacencies, and its data.F hgeometryPadjacent vertices + data on the edge. Adjacencies are given in arbitrary order/.-,3210BCDFGE/.-,BCDFGE3210(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gk|4L hgeometry&Note that the functor instance is in vU hgeometry#Embedded, *connected*, planar grapha hgeometryrConstruct a plane graph from a simple polygon. It is assumed that the polygon is given in counterclockwise order..the interior of the polygon will have faceId 0Ipre: the input polygon is given in counterclockwise order running time: O(n).) hgeometry+Constructs a planar from the given verticesb hgeometry"Constructs a connected plane graph3pre: The segments form a single connected componentrunning time:  O(n\log n)c hgeometryGet the number of verticesnumVertices smallG4d hgeometryGet the number of DartsnumDarts smallG10e hgeometryGet the number of EdgesnumEdges smallG5f hgeometryGet the number of facesnumFaces smallG3g hgeometryEnumerate all verticesvertices' smallG-[VertexId 0,VertexId 1,VertexId 2,VertexId 3]h hgeometry7Enumerate all vertices, together with their vertex datamapM_ print $ vertices smallG>(VertexId 0,VertexData {_location = Point2 [0,0], _vData = 0})>(VertexId 1,VertexData {_location = Point2 [2,2], _vData = 1})>(VertexId 2,VertexData {_location = Point2 [2,0], _vData = 2})?(VertexId 3,VertexData {_location = Point2 [-1,4], _vData = 3})i hgeometryEnumerate all dartsj hgeometry&Get all darts together with their datak hgeometry6Enumerate all edges. We report only the Positive dartsl hgeometry6Lens to access the raw dart data, use at your own riskm hgeometrylens to access the Dart Datan hgeometryLens to access face datap hgeometryMEnumerate all edges with their edge data. We report only the Positive darts.mapM_ print $ edges smallG(Dart (Arc 0) +1,"0->2")(Dart (Arc 1) +1,"0->1")(Dart (Arc 2) +1,"0->3")(Dart (Arc 4) +1,"1->2")(Dart (Arc 3) +1,"1->3")q hgeometry&Enumerate all faces in the plane graphr hgeometryAll faces with their face data.mapM_ print $ faces smallG(FaceId 0,"OuterFace")(FaceId 1,"A")(FaceId 2,"B")s hgeometryHReports the outerface and all internal faces separately. running time: O(n)t hgeometry+Reports all internal faces. running time: O(n)u hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1)tailOf (dart 0 "+1") smallG VertexId 0v hgeometry%The vertex this dart is heading in torunning time: O(1)headOf (dart 0 "+1") smallG VertexId 2w hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1)endPoints (dart 0 "+1") smallG(VertexId 0,VertexId 2)x hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k is the output size!incidentEdges (VertexId 1) smallG1[Dart (Arc 1) -1,Dart (Arc 4) +1,Dart (Arc 3) +1]y hgeometrypAll edges incident to vertex v in incoming direction (i.e. pointing into v) in counterclockwise order around v.running time: O(k)6, where (k) is the total number of incident edges of v!incomingEdges (VertexId 1) smallG1[Dart (Arc 1) +1,Dart (Arc 4) -1,Dart (Arc 3) -1]z hgeometrypAll edges incident to vertex v in incoming direction (i.e. pointing into v) in counterclockwise order around v.running time: O(k)6, where (k) is the total number of incident edges of v!outgoingEdges (VertexId 1) smallG1[Dart (Arc 1) -1,Dart (Arc 4) +1,Dart (Arc 3) +1]{ hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output size neighboursOf (VertexId 1) smallG"[VertexId 0,VertexId 2,VertexId 3]| hgeometryyGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v in clockwise direction.running time: O(1)%nextIncidentEdge (dart 1 "+1") smallGDart (Arc 2) +1} hgeometryvGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v (in clockwise order)running time: O(1)%prevIncidentEdge (dart 1 "+1") smallGDart (Arc 0) +1~ hgeometry The face to the left of the dartrunning time: O(1).leftFace (dart 1 "+1") smallGFaceId 2leftFace (dart 1 "-1") smallGFaceId 1leftFace (dart 2 "+1") smallGFaceId 0leftFace (dart 2 "-1") smallGFaceId 2 hgeometry!The face to the right of the dartrunning time: O(1).rightFace (dart 1 "+1") smallGFaceId 1rightFace (dart 1 "-1") smallGFaceId 2rightFace (dart 2 "+1") smallGFaceId 2rightFace (dart 2 "-1") smallGFaceId 0 hgeometry Get the next edge along the facerunning time: O(1).nextEdge (dart 1 "+1") smallGDart (Arc 4) +1 hgeometry$Get the previous edge along the facerunning time: O(1).prevEdge (dart 1 "+1") smallGDart (Arc 0) -1 hgeometrytThe darts bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size. hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reported hgeometry`Gets a dart bounding this face. I.e. a dart d such that the face lies to the right of the dart. hgeometrywThe vertices bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size. hgeometryTraverse the vertices(^.vertexData)  $ traverseVertices (i x -> Just (i,x)) smallG Just [(VertexId 0,0),(VertexId 1,1),(VertexId 2,2),(VertexId 3,3)] >>> traverseVertices (i x -> print (i,x)) smallG >> pure () (VertexId 0,0) (VertexId 1,1) (VertexId 2,2) (VertexId 3,3) hgeometryTraverses the darts5traverseDarts (\d x -> print (d,x)) smallG >> pure () (Dart (Arc 0) +1,"0->2")(Dart (Arc 0) -1,"2->0")(Dart (Arc 1) +1,"0->1")(Dart (Arc 1) -1,"1->0")(Dart (Arc 2) +1,"0->3")(Dart (Arc 2) -1,"3->0")(Dart (Arc 3) +1,"1->3")(Dart (Arc 3) -1,"3->1")(Dart (Arc 4) +1,"1->2")(Dart (Arc 4) -1,"2->1") hgeometryTraverses the faces5traverseFaces (\i x -> print (i,x)) smallG >> pure ()(FaceId 0,"OuterFace")(FaceId 1,"A")(FaceId 2,"B") hgeometry.Getter for the data at the endpoints of a dartrunning time: O(1) hgeometry/Data corresponding to the endpoints of the dartrunning time: O(1) hgeometrygets the id of the outer facerunning time: O(n) hgeometry[gets a dart incident to the outer face (in particular, that has the outerface on its left)running time: O(n) hgeometry"Reports all edges as line segments!mapM_ print $ edgeSegments smallGa(Dart (Arc 0) +1,LineSegment (Closed (Point2 [0,0] :+ 0)) (Closed (Point2 [2,0] :+ 2)) :+ "0->2")a(Dart (Arc 1) +1,LineSegment (Closed (Point2 [0,0] :+ 0)) (Closed (Point2 [2,2] :+ 1)) :+ "0->1")b(Dart (Arc 2) +1,LineSegment (Closed (Point2 [0,0] :+ 0)) (Closed (Point2 [-1,4] :+ 3)) :+ "0->3")a(Dart (Arc 4) +1,LineSegment (Closed (Point2 [2,2] :+ 1)) (Closed (Point2 [2,0] :+ 2)) :+ "1->2")b(Dart (Arc 3) +1,LineSegment (Closed (Point2 [2,2] :+ 1)) (Closed (Point2 [-1,4] :+ 3)) :+ "1->3") hgeometry[Given a dart and the graph constructs the line segment representing the dart. The segment \overline{uv}) is has u as its tail and v as its head.O(1) hgeometryThe polygon describing the face runningtime: O(k), where k is the size of the face. hgeometryAlias for rawFace Boundary runningtime: O(k), where k is the size of the face. hgeometry#Lists all faces of the plane graph. hgeometry_Labels the edges of a plane graph with their distances, as specified by the distance function.a hgeometry data inside hgeometrydata outside the polygonO !$#"%&)('*+LMUVWXY`abcdefghijklmnopqrstuvwxyz{|}~OUV`&LMXWYabcefdghkpqrtsijvu*wxyz{|}~)('onml $#"+!%H(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk hgeometry%Reads a plane graph from a bytestring hgeometry$Writes a plane graph to a bytestring hgeometryTransforms the plane graph into adjacency lists. For every vertex, the adjacent vertices are given in counter clockwise order.See toAdjacencyLists' for notes on how we handle self-loops.running time: O(n) hgeometryGiven the AdjacencyList representation of a plane graph, construct the plane graph representing it. All the adjacencylists should be in counter clockwise order.running time: O(n) hgeometry1Orders the adjacencylists of a plane graph (with nU vertices) (in Adj repr) so that they are all counter-clockwise around the vertices.running time:  O(n \log n)j(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_gkR !$#"%&)('*+LMUVWXY`abcdefghijklmnopqrstuvwxyz{|}~RUV`&LMXWYabcefdghkpqrtsijvu*wxyz{|}~)('onml $#"+!%I(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk hgeometry=The Face data consists of the data itself and a list of holes hgeometry>Helper type for the data that we store in a planar subdivision hgeometryComponentId type hgeometry6Helper data type and type family to Wrap a proxy type. hgeometryget the dataVal of a Raw hgeometryFace data, if the face is an inner face, store the component and faceId of it. If not, this face must be the outer face (and thus we can find all the face id's it correponds to through the FaceData).J(C) Frank Staalssee the LICENSE file Frank StaalsNone!%&',-.14567=>?@AHMPSUVX_ghk;- hgeometryA planarsubdivision is essentially a bunch of plane-graphs; one for every connected component. These graphs store the global ID's (darts, vertexId's, faceId's) in their data values. This essentially gives us a mapping between the two.note that a face may actually occur in multiple graphs, hence when we store the edges to the the holes, we store the global edgeId's rather than the local edgeId (dart)'s.%invariant: the outerface has faceId 0 hgeometryA connected component.For every face f, and every hole in this face, the facedata points to a dart d on the hole s.t. this dart has the face f on its left. i.e. leftFace d = f hgeometryNData type that expresses whether or not we are inside or outside the polygon. hgeometry0Constructs a planarsubdivision from a PlaneGraph runningTime: O(n) hgeometrynGiven a (connected) PlaneGraph and a dart that has the outerface on its left | Constructs a planarsubdivision runningTime: O(n) hgeometryrConstruct a plane graph from a simple polygon. It is assumed that the polygon is given in counterclockwise order..the interior of the polygon will have faceId 0Ipre: the input polygon is given in counterclockwise order running time: O(n). hgeometry*Constructs a connected planar subdivision.Cpre: the segments form a single connected component running time:  O(n\log n) hgeometryGet the number of verticesnumVertices myGraph1 hgeometryGet the number of verticesnumVertices myGraph4 hgeometryGet the number of DartsnumDarts myGraph12 hgeometryGet the number of EdgesnumEdges myGraph6 hgeometryGet the number of facesnumFaces myGraph4 hgeometryEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3] hgeometry7Enumerate all vertices, together with their vertex data hgeometryEnumerate all darts hgeometry6Enumerate all edges. We report only the Positive darts hgeometryMEnumerate all edges with their edge data. We report only the Positive darts.mapM_ print $ edges myGraph(Dart (Arc 2) +1,"c+")(Dart (Arc 1) +1,"b+")(Dart (Arc 0) +1,"a+")(Dart (Arc 5) +1,"g+")(Dart (Arc 4) +1,"e+")(Dart (Arc 3) +1,"d+") hgeometryDEnumerates all faces with their face data exlcluding the outer face hgeometrylens to access the Dart Data hgeometrySLens to the facedata of the faces themselves. The indices correspond to the faceIds hgeometry[Lens to the facedata of the vertexdata themselves. The indices correspond to the vertexId's hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1) hgeometry%The vertex this dart is heading in torunning time: O(1) hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1) hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k! is the number of edges reported. hgeometrydGiven a dart d that points into some vertex v, report the next dart e in the cyclic order around v.running time: O(1) hgeometrypAll edges incident to vertex v in incoming direction (i.e. pointing into v) in counterclockwise order around v.running time: O(k)6, where (k) is the total number of incident edges of v hgeometryuAll edges incident to vertex v in outgoing direction (i.e. pointing away from v) in counterclockwise order around v.running time: O(k)6, where (k) is the total number of incident edges of v hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output size hgeometry The face to the left of the dartrunning time: O(1). hgeometry!The face to the right of the dartrunning time: O(1). hgeometryThe darts on the outer boundary of the face, for internal faces the darts are in clockwise order. For the outer face the darts are in counterclockwise order, and the darts from various components are in no particular order.running time: O(k), where k is the output size.* hgeometry3Get the local face and component from a given face. hgeometryThe vertices of the outer boundary of the face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size. hgeometryLists the holes in this face, given as a list of darts to arbitrary darts on those faces. The returned darts are on the outside of the hole, i.e. they are incident to the given input face:/all (\d -> leftFace d ps == fi) $ holesOf fi psrunning time: O(k), where k! is the number of darts returned.+ hgeometryENote that using the setting part of this lens may be very expensive!!  hgeometry.Getter for the data at the endpoints of a dartrunning time: O(1)  hgeometry/data corresponding to the endpoints of the dartrunning time: O(1)  hgeometrygets the id of the outer facerunning time: O(1)  hgeometry"Reports all edges as line segments hgeometryLGiven a dart and the subdivision constructs the line segment representing itO(1) hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reported hgeometry)Constructs the outer boundary of the faceO(k), where k4 is the complexity of the outer boundary of the face hgeometry)Constructs the boundary of the given faceO(k), where k is the complexity of the face hgeometry5Lists all *internal* faces of the planar subdivision. hgeometry data inside hgeometrydata outside the polygon[ !$#"%&)('*+LMUWX     [!%LMXW&U* )('     $#"+K(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk  hgeometry1Merge a pair of *disjoint* planar subdivisions, unifying their outer face. The given function is used to merge the data corresponding to the outer face. The subdivisions are merged pairwise, no guarantees are given about the order in which they are merged. Hence, it is expected that f is commutative.running time:  O(n\log n), where n( is the total size of the subdivisions. hgeometryMerge a pair of *disjoint* planar subdivisions, unifying their outer face. For the outerface data it simply takes the data of the first subdivision. runningtime: O(n) hgeometryMerge a pair of *disjoint* planar subdivisions. In particular, this function unifies the structure assuming that the two subdivisions share the outer face. runningtime: O(n), hgeometryjTakes care of actually combining the vectors with data. only thing left is how to merge the raw face data- hgeometryShift the indices in a planar subdiv by the given numbers (componentId;vertexId,darts,faceIds). Note that the result is not really a valid planar subdivision, so be careful when using this! hgeometryThe disjoint "holes" hgeometryHow to merge the face data hgeometry-Face in which to embed the given subdivisions hgeometrythe outer subdivision hgeometryThe hole hgeometry-How to merge the face data (hole value first) hgeometry-Face in which to embed the given subdivisions hgeometrythe outer subdivision hgeometry'how to merge the data of the outer face, hgeometryhow to merge the raw face dataL(C) Frank Staalssee the LICENSE file Frank StaalsNone %&',-.14567=>?@AHMPSUVX_ghk8  hgeometry5Constructs a planar subdivision from a collection of k( disjoint polygons of total complexity O(n).Jpre: The boundary of the polygons is given in counterclockwise orientation runningtime: O(n\log n\log k)& in case of polygons with holes, and  O(n\log k) in case of simple polygons.! hgeometry Version of   that accepts C s as input." hgeometryConstruct a planar subdivision from a polygon. Since our PlanarSubdivision models only connected planar subdivisions, this may add dummy/invisible edges.Ppre: The outer boundary of the polygons is given in counterclockwise orientationrunning time: O(n) for a simple polygon,  O(n\log n) for a polygon with holes.  hgeometryouter face data hgeometrythe disjoint polygons! hgeometryouter face data hgeometrythe disjoint polygons" hgeometry data inside hgeometrydata outside the polygon^ !$#"%&)('*+LMUWX      !" !"M(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk> % hgeometry;Data type representing a two dimensional planar arrangement2 hgeometryBuilds an arrangement of n linesrunning time:  O(n^2\log n3 hgeometryConstructs the arrangemnet inside the box. note that the resulting box may be larger than the given box to make sure that all vertices of the arrangement actually fit.running time:  O(n^2\log n4 hgeometryConstructs the arrangemnet inside the box. (for parts to be useful, it is assumed this boxfits at least the boundingbox of the intersections in the Arrangement)9 hgeometry5Constructs a boundingbox containing all intersectionsrunning time: O(n^2), where n is the number of input lines: hgeometryComputes all intersections; hgeometry1Computes the intersections with a particular side< hgeometryHConstructs the unbounded intersections. Reported in clockwise direction.= hgeometryGLinks the vertices of the outer boundary with those in the subdivision@ hgeometrynGiven a predicate that tests if two elements of a CSeq match, find a rotation of the seqs such at they match.Running time: O(n)A hgeometry\Given an Arrangement and a line in the arrangement, follow the line through he arrangement.B hgeometry4Find the starting point of the line the arrangementC hgeometrybGiven a point on the boundary of the boundedArea box; find the vertex this point corresponds to.running time:  O(\log n)basically; maps every point to a tuple of the point and the side the point occurs on. We then binary search to find the point we are looking for.D hgeometryOFind the starting dart of the given vertex v. Reports a dart s.t. tailOf d = v running me: O(k) where k is the degree of the vertexE hgeometryGiven a dart d that incoming to v (headOf d == v), find the outgoing dart colinear with the incoming one. Again reports dart d' s.t. tailOf d' = vrunning time: O(k)1, where k is the degree of the vertex d points to%&*)('+./0123456789:;<=>?@ABCDE+%&*)('10/.23456789:;<=>?@ABCDEk(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk@%&'()*+./01234ABCDE%&'()*/0.1+234ABCDENNone%&',-.14567=>?@AHMPSUVX_gkJBI hgeometryUGiven a list of original edges and a list of diagonals, creates a planar-subdivisionrunning time:  O(n\log n)J hgeometryUGiven a list of original edges and a list of diagonals, creates a planar-subdivisionrunning time:  O(n\log n)I hgeometry3A counter-clockwise edge along the outer boundary hgeometryremaining original edges hgeometry diagonalsJ hgeometry3A counter-clockwise edge along the outer boundary hgeometryremaining original edges hgeometry diagonalsFHGIJFHGIJONone%&',-.14567=>?@AHMPSUVX_gk[> . hgeometry*for every e_i, the id of the helper vertexT hgeometry$assigns a vertex type to each vertexZpre: Both the outer boundary and the inner boundary of the polygon are given in CCW order.running time: O(n)./ hgeometry$assigns a vertex type to each vertex&pre: the polygon is given in CCW orderrunning time: O(n).0 hgeometryp  q = p.y < q.y || p.y == q.y && p.x q.yY hgeometrymGiven a polygon, find a set of non-intersecting diagonals that partition the polygon into y-monotone pieces.running time:  O(n\log n)Z hgeometryPComputes a set of diagionals that decompose the polygon into y-monotone pieces.=pre: the polygon boundary is given in counterClockwise order.running time:  O(n\log n)1 hgeometry1Adds edge (i,j) if e_j's helper is a merge vertex2 hgeometry-Get the helper of edge i, and its vertex type3 hgeometry`finds the edge j to the left of v_i, and connect v_i to it if the helper of j is a merge vertex4 hgeometryBreturns True if v the interior of the polygon is to the right of v NOPQRSTYZ ZYNOPQRSTPNone%&',-.14567=>?@AHMPSUVX_gkha hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)b hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)c hgeometryoGiven a y-monotone polygon in counter clockwise order computes the diagonals to add to triangulate the polygon-pre: the input polygon is y-monotone and has n \geq 3 verticesrunning time: O(n)h hgeometry5test if m does not block the line segment from v to ui hgeometry8given a comparison function, merge the two ordered listsj hgeometrykWhen the polygon is in counter clockwise order we return (leftChain,rightChain) ordered from the top-down.if there are multiple points with the maximum yCoord we pick the rightmost one, if there are multiple point with the minimum yCoord we pick the leftmost one.running time: O(n)[\]^_`abcdefghijk`]^_abc\[defghijkQNone%&',-.14567=>?@AHMPSUVX_gkrn hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)o hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)p hgeometryMComputes a set of diagaonals that together triangulate the input polygon of n vertices.running time:  O(n \log n)q hgeometryMComputes a set of diagaonals that together triangulate the input polygon of ns vertices. Returns a copy of the input polygon, whose boundaries are oriented in counter clockwise order, as well.running time:  O(n \log n)nopqnopqR(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk}fr hgeometryeNeighbours are stored in clockwise order: i.e. rotating right moves to the next clockwise neighbour.y hgeometryRotating Right  - rotate clockwise| hgeometry*ST' is a strict triple (m,a,x) containing:fm: a Map, mapping edges, represented by a pair of vertexId's (u,v) with u < v, to arcId's."a: the next available unused arcID0x: the data value we are interested in computing hgeometry2convert the triangulation into a planarsubdivisionrunning time: O(n). hgeometry,convert the triangulation into a plane graphrunning time: O(n).rsvutwxy|}~yxwrsvut~}|SNone%&',-.14567=>?@AHMPSUVX_gk. hgeometryNaive O(n^4) time implementation of the delaunay triangulation. Simply tries each triple (p,q,r) and tests if it is delaunay, i.e. if there are no other points in the circle defined by p, q, and r.pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away) hgeometrypGiven a list of edges, as vertexId pairs, construct a vector with the adjacency lists, each in CW sorted order. hgeometryGiven a particular point u and a list of points vs, sort the points vs in CW order around u. running time: O(m log m), where m=|vs| is the number of vertices to sort. hgeometry0Given a list of faces, construct a list of edges hgeometryaTest if the given three points form a triangle in the delaunay triangulation. running time: O(n)TNone%&',-.14567=>?@AHMPSUVX_gk- hgeometry7Computes the delaunay triangulation of a set of points.Running time:  O(n \log n)C (note: We use an IntMap in the implementation. So maybe actually  O(n \log^2 n))pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away) hgeometryMapping that says for each vtx in the convex hull what the first entry in the adj. list should be. The input polygon is given in Clockwise order hgeometryXGiven a polygon; construct the adjacency list representation pre: at least two elements hgeometry&Merge the two delaunay triangulations.running time: O(n), (although we cheat a bit by using a IntMap) hgeometry'Merges the two delaunay traingulations. hgeometry'rotates'= around r and removes all neighbours of r that violate the delaunay condition. Returns the first vertex (as a Neighbour of r) that should remain in the Delaunay Triangulation, as well as a boolean A that helps deciding if we merge up by rotating left or rotating right (See description in the paper for more info) hgeometry&The code that does the actual rotating hgeometrySymmetric to rotateR hgeometry=The code that does the actual rotating. Symmetric to rotateR' hgeometryereturns True if the forth point (vertex) does not lie in the disk defined by the first three points. hgeometry(Inserts an edge into the right position. hgeometryNmake sure that the first vtx in the adj list of v is its predecessor on the CH hgeometryhInserts an edge (and makes sure that the vertex is inserted in the correct. pos in the adjacency lists) hgeometryDeletes an edge hgeometry!Lifted version of Convex.IsLeftOf hgeometry"Lifted version of Convex.IsRightOf hgeometryan unsafeO version of rotateTo that assumes the element to rotate to occurs in the list. hgeometryIAdjacency lists are stored in clockwise order, so pred means rotate right hgeometryKAdjacency lists are stored in clockwise order, so pred and succ rotate left hgeometry%Removes duplicates from a sorted list hgeometry lower tangent hgeometry upper tangentU(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkk hgeometryComputes the Euclidean Minimum Spanning Tree. We compute the Delaunay Triangulation (DT), and then extract the EMST. Hence, the same restrictions apply as for the DT:pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away)running time:  O(n \log n)V(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gk  hgeometry0A basic camera data type. The fields stored are:the camera position,Hthe raw camera normal, i.e. a unit vecotr into the center of the screen,Kthe raw view up vector indicating which side points "upwards" in the scene,bthe viewplane depth (i.e. the distance from the camera position to the plane on which we project),;the near distance (everything closer than this is clipped),Dthe far distance (everything further away than this is clipped), andthe screen dimensions.5 hgeometry1unit vector from camera into center of the screen6 hgeometry!viewUp; assumed to be unit vector hgeometryVLens to get and set the Camera normal, makes sure that the vector remains normalized. hgeometryQLens to get and set the viewUp vector. Makes sure the vector remains normalized. hgeometry+Full transformation that renders the figure hgeometry2Translates world coordinates into view coordinates hgeometry(Transformation into viewport coordinates hgeometry#constructs a perspective projection hgeometry[Rotates coordinate system around the camera, such that we look in the negative z direction hgeometryFlips the y and z axis.W(C) Frank Staalssee the LICENSE file Frank StaalsNone%&',-.14567=>?@AHMPSUVX_gkR hgeometry"Rendering function for a triangle. hgeometryRender a point hgeometryRenders a line segment hgeometryGeneric Rendering Function hgeometryProjection function hgeometryThe camera transform hgeometryThe thing we wish to transform7lmnopqopropsoptopuopvopwopxopyopzop{op|op}op~opopopopopopopopop[op[oooooooooooooooooooooooooooYYYYY         ! " # $ % & ' ( ) ( * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > > ? @ A B C D E F F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ] ^ _ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y > > ? z { B C | E } } ~    J K                    ] ] ^        R S U V W X     f e           v x y                 ]]]]]] ]!]"]#]$]%]&]'](])^*^+^,^*^-^.^/^0^1^2^3^4_5_6_7_8_9_:_;_<`=`>`?`@`A`B`C`DEEFFG>>HI{RJKULMNOPQRSTUBC|VWXYZ[\]^_L`abccdeFGFfgKhiUjklmnopqrstuvwxyyzR{|}BC~b      !"#$%&''()*+,-./01233456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`]abcdefghijklmnopqrstuvwxyyz{|}}~                     !!"""""""""""""""""""""""""""#$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%& &c& & & & &&&&&K&&&&&&&&&''''''' '!'"'#'''$''%'&''''('')'*''+'','-'.'/'0'1'2'3'4'5'6'7(8(8(9(:(;((<(=(>(?(@(A(B(C(D(E(F(G(H(I(J(K(L(M(N(O)P)Q)R)S)T*U*U*V*W*X*Y*Z*[*\*]*^*_*`*a*b*c*d*e*f*g*h*i*j*k*l*m*n*o+p+p+q+r+s+t+u+v+v+w+x+y+z+{+|+}+~+++++++++,,,,,,,,,,,,,,,,,,,,-------------------...//// ////////////////////////////////000000000000000000000111111111111111111111111111y11111Q11111111222222222 2 2 2 2 2222222222222222ccc c!c cc"c#c$c%c&c'c(c)c*c+c,c-cc.c/c0c1c2c3cc4c5c6c7c8c9c:c;c<c=c>c?c@dAdB4C4C4D4E4F4G4H4I4J4K4L44M4N4O4P4Q4R4S4T4U5V5V5W5X5Y5Z5[5\5]5^5_5`5a5b6>6>6c6d6e6f66g6C6B6h6h6i6j6k6l6m6n6o6p6|6q6r6s6t6u6v6w6x6y6z666{6|6}6~666666677777777777777777777777777777eeee8888999999999999999999::::::::3;;;;;;;;;;;;;;;;;;<<====>>>??@AAAAAAABBBBBBCCCCCCCDDDDDDEEEEEFFFFFFFGGG       !"#$%&'()a*+,-./0123456789:;<=>?@AABCDEFGHIJHKHLHMHNHOHPHQIRIRISITIUIUIVIWIXIYIYIZI[I\I]I^I_I`IaIbIcIdIeIfIgIhIiIjIkIlImInIoIpIqIrIsItIuIuIvIwIIxIyIzI{I|I}I~IIIIIJJJJJJJJJJJJ JJJJJJJJJJJJJJJJJ$J%JJ'J!J"J#J(J)JaJ*J.J+J,J-J0J1JJ7JJ9JJ=J>J?JAJAJ5JBJCJDJJJJJJJJKKKKKLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSTTTTTTTTT T T T T TWTTTXTTTTTTTTTTTUUVVVVVV V!V"V#V$V%V&V'V(V)V*V+V,V-V.W/W0W1W2X3X4X5X6X7X8X9X:X;X<X=X>X?X@XABCDoEFoEGoEHoEHoEoEIoEJoEKoELoEMoENopopJ O P QR]9]8^S_T_U>WVWXYZ[\]^_`aab1c1dcecf4g4h4i4jklmeneof-fpfqf,f*grggrggsht:u:v:w:x:ykz{:|:}:~<=@@AAACFFFGJJ8KKOOOOOOOVV)hgeometry-0.11.0.0-5Q7X7STHtn33ZJbJEL0QVyData.Geometry.VectorData.Geometry.LineSegmentData.PlaneGraph.CoreData.PlaneGraph.AdjRepAlgorithms.Geometry.SoS Algorithms.Geometry.SoS.SymbolicData.Geometry.DirectionsData.Geometry.Interval.UtilData.Geometry.PropertiesData.Geometry.IntervalData.Geometry.IntervalTreeData.Geometry.RangeTree.Measure!Data.Geometry.SegmentTree.Generic Data.Geometry.Vector.VectorFixed&Data.Geometry.Vector.VectorFamilyPeano!Data.Geometry.Vector.VectorFamilyData.Geometry.PointData.Geometry.RangeTree.GenericData.Geometry.RangeTree Data.Geometry.PrioritySearchTree,Algorithms.Geometry.FrechetDistance.Discrete0Algorithms.Geometry.ClosestPair.DivideAndConquerData.Geometry.MatrixData.Geometry.TransformationData.Geometry.BoundaryData.Geometry.Line.InternalData.Geometry.SubLineData.Geometry.Box.Internal1Algorithms.Geometry.LineSegmentIntersection.Types1Algorithms.Geometry.LineSegmentIntersection.Naive:Algorithms.Geometry.LineSegmentIntersection.BentleyOttmannData.Geometry.Box.Corners Data.Geometry.QuadTree.QuadrantsData.Geometry.Box.SidesData.Geometry.BoxData.Geometry.QuadTree.CellData.Geometry.QuadTree.SplitData.Geometry.QuadTree.TreeData.Geometry.QuadTreeData.Geometry.PolyLineData.Geometry.LineData.Geometry.SlabData.Geometry.HyperPlaneData.Geometry.HalfLineData.Geometry.HalfSpaceData.Geometry.DualityData.Geometry.KDTreeData.Geometry.BezierSplineData.Geometry.BallData.Geometry.TriangleData.Geometry.PolygonData.Geometry.Polygon.ConvexData.Geometry.Ellipse8Algorithms.Geometry.WellSeparatedPairDecomposition.Types7Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD9Algorithms.Geometry.PolyLineSimplification.DouglasPeucker+Algorithms.Geometry.LinearProgramming.Types-Algorithms.Geometry.LinearProgramming.LP2DRIC/Algorithms.Geometry.SmallestEnclosingBall.Types/Algorithms.Geometry.SmallestEnclosingBall.Naive-Algorithms.Geometry.SmallestEnclosingBall.RIC"Algorithms.Geometry.Diameter.Naive+Algorithms.Geometry.LineSegmentIntersection(Algorithms.Geometry.ConvexHull.QuickHull)Algorithms.Geometry.ConvexHull.GrahamScan(Algorithms.Geometry.LowerEnvelope.DualCH/Algorithms.Geometry.ConvexHull.DivideAndConquer(Algorithms.Geometry.RedBlueSeparator.RIC$Algorithms.Geometry.ConvexHull.Naive*Algorithms.Geometry.ConvexHull.JarvisMarch%Algorithms.Geometry.ClosestPair.NaiveData.PlaneGraph.IO#Data.Geometry.PlanarSubdivision.Raw%Data.Geometry.PlanarSubdivision.Basic%Data.Geometry.PlanarSubdivision.MergeData.Geometry.PlanarSubdivision"Data.Geometry.Arrangement.Internal.Algorithms.Geometry.PolygonTriangulation.Types5Algorithms.Geometry.PolygonTriangulation.MakeMonotone