(ns e2-2-3 (:use [util.util :only (close-enough? tolerance)]) (:use [clojure.contrib.test-is :only (deftest is run-tests)]) (:use [clojure.contrib.generic.math-functions :only (abs acos sqr sqrt)])) | |

(defn make-point [x y] (list x y)) | |

(defn x-point [a] (first a)) | |

(defn y-point [a] (second a)) | |

(defn same-point? [a b] (= a b)) | |

'a' and 'b' are points on the XY coordinate axis | (defn make-segment [a b] (list a b)) |

(defn start-segment [a] (first a)) | |

(defn end-segment [a] (second a)) | |

(defn same-segment? [a b] (= a b)) | |

Subtracts the start of the segment from its end and returns the resulting point I don't know how this operation is named correctly, hence the basepoint part. | (defn basepoint-segment [a] (make-point (- (x-point (end-segment a)) (x-point (start-segment a))) (- (y-point (end-segment a)) (y-point (start-segment a))))) |

(defn midpoint-segment [a] (let [base-point (basepoint-segment a)] (make-point (+ (/ (x-point base-point) 2) (x-point (start-segment a))) (+ (/ (y-point base-point) 2) (y-point (start-segment a)))))) | |

(def *point00* (make-point 0 0)) (def *point11* (make-point 1 1)) (def *point22* (make-point 2 2)) | |

(deftest midpoint-test (is (= (midpoint-segment (make-segment *point00* *point11*)) (make-point 0.5 0.5))) (is (= (midpoint-segment (make-segment (make-point 2 2) (make-point 3 3))) (make-point 2.5 2.5))) (is (= (midpoint-segment (make-segment (make-point -2 -2) (make-point 3 3))) (make-point 0.5 0.5)))) | |

length of the given segment as a sqrt(x^2 + y^2) | (defn length-segment [s] (let [base-point (basepoint-segment s)] (sqrt (+ (sqr (x-point base-point)) (sqr (y-point base-point)))))) |

the dot product of two vectors | (defn dot-product [a b] (let [base-point-a (basepoint-segment a) base-point-b (basepoint-segment b)] (+ (* (x-point base-point-a) (x-point base-point-b)) (* (y-point base-point-a) (y-point base-point-b))))) |

normalizes the given segment (treating it as a 2d vector) | (defn normalize [v] (let [base-point (basepoint-segment v) length (length-segment v)] (make-segment (make-point 0 0) (make-point (/ (x-point base-point) length) (/ (y-point base-point) length))))) |

dot product of orthogonal normalized vectors is equal to 0 as dot product is the cosine of the angle between those vectors and cos(90) = 0 | (defn orthogonal-segments? [a b] (= (dot-product (normalize a) (normalize b)) 0)) |

Makes rectangle out of a point and two segments satisfying both conditions: 1. both segments must have equal x-points 2. the angle between the segments must equal 90 degrees | (defn make-rect-seg [width height] (if (not (orthogonal-segments? width height)) (println "Width and Height segments aren't orthogonal!") (if (not (and (same-point? (x-point (start-segment height)) (x-point (start-segment width))) (same-point? (y-point (start-segment height)) (y-point (start-segment width))))) (println "Segments do not start at the same point!") ; valid data received [width height]))) |

Makes a rectangle out of 4 points.
| (defn make-rect-pts [a b c d] (if (not (orthogonal-segments? (make-segment a b) (make-segment a c))) (println "Width and Height segments aren't orthogonal!") [a b c d])) |

(defn width-rect [r] (length-segment (get r 0))) | |

(defn height-rect [r] (length-segment (get r 1))) | |

(defn area-rect [r] (* (width-rect r) (height-rect r))) | |

(def *segment0040* (make-segment (make-point 0 0) (make-point 4 0))) (def *segment0004* (make-segment (make-point 0 0) (make-point 0 4))) (def *segment5566* (make-segment (make-point 5 5) (make-point 6 6))) (def *segment5564* (make-segment (make-point 5 5) (make-point 6 4))) | |

(deftest area-test (is (= (area-rect (make-rect-seg *segment0040* *segment0004*)) 16)) (is (close-enough? (area-rect (make-rect-seg *segment5566* *segment5564*)) 2 tolerance))) | |

(defn perimeter-rect [r] (+ (* 2 (width-rect r)) (* 2 (height-rect r)))) | |

(deftest perimeter-test (is (= (perimeter-rect (make-rect-seg *segment0040* *segment0004*)) 16)) (is (close-enough? (perimeter-rect (make-rect-seg *segment5566* *segment5564*)) (* (sqrt 2) 4) tolerance))) | |