-
Notifications
You must be signed in to change notification settings - Fork 16
/
basic-point.lisp
89 lines (75 loc) · 2.77 KB
/
basic-point.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
(in-package :2d-geometry)
;;;; This file implements basic functions operating on points. A point is any object with methods (x
;;;; object) (y object).
(defclass point ()
((x :reader x :initarg :x :initform 0)
(y :reader y :initarg :y :initform 0))
(:documentation "A point on a plane, with cartesian coordinates."))
(defmethod print-object ((object point) stream)
(print-unreadable-object (object stream :type t)
(format stream "~a,~a" (x object) (y object))))
(defun make-point (x y &optional (point-type 'point))
"Create a new point like object."
(make-instance point-type :x x :y y))
(defun point-equal-p (point1 point2)
"Checks if two points are geometrically equal."
(and (= (x point1)(x point2))
(= (y point1)(y point2))))
(defun coords-to-points (&rest coord-list)
"Coordinate list (x1 y1 x2 y2 ... xn yn) to point list"
(assert (zerop (mod (length coord-list) 2)))
(iterate (for (x y . nil) on coord-list by #'cddr)
(collect (make-point x y))))
(defun left-p (a b c)
"Is c to the left of the oriented line defined by a->b?"
(> (area-triangle-vertices (x a)(y a)(x b)(y b) (x c)(y c)) 0))
(defun left-on-p (a b c)
"Is c to the left or on the oriented line defined by a->b?"
(>= (area-triangle-vertices (x a)(y a)(x b)(y b) (x c)(y c)) 0))
(defun colinear-p (a b c)
"Is c on the line defined by a->b?"
(zerop (area-triangle-vertices (x a)(y a)(x b)(y b) (x c)(y c))))
(defun between-p (a b c)
"Is c colinear with a->b and lies between them?"
(when (colinear-p a b c)
(if (= (y a)(y b))
(or (and (>= (x c)(x a))
(<= (x c)(x b)))
(and (>= (x c)(x b))
(<= (x c)(x a))))
(or (and (>= (y c)(y a))
(<= (y c)(y b)))
(and (>= (y c)(y b))
(<= (y c)(y a)))))))
(defun xor (p q)
"Exlusive or logical operation."
(if (or (and p q)
(and (not p)(not q)))
nil
t))
(defun intersect-proper-p (a b c d)
"Do segments a->b and c->d intersect?"
(unless (or (colinear-p a b c)
(colinear-p a b d)
(colinear-p c d a)
(colinear-p c d b))
(and (xor (left-p a b c)
(left-p a b d))
(xor (left-p c d a)
(left-p c d b)))))
(defun intersect-p (a b c d)
"Do segments a->b and c->d intersect?"
(if (intersect-proper-p a b c d)
t
(or (between-p a b c)
(between-p a b d)
(between-p c d a)
(between-p c d b))))
(defun point-sort-fun (point1 point2)
"Order points by increasing x then y."
(if (= (x point1)(x point2))
(if (= (y point1)(y point2))
(if (typep point1 'event-endpoint)
(eql (direction point1) 'right))
(< (y point1)(y point2)))
(< (x point1)(x point2))))