<commit_before>#+SETUPFILE: ../../src/setup.org

* thi.ng.geom.plane

** Constructor
#+BEGIN_SRC clojure :noweb-ref ctors
  (defn plane
    [n w] (thi.ng.geom.types.Plane. (g/normalize (vec3 n)) w))

  (defn plane-with-p
    [p n]
    (let [n (g/normalize (vec3 n))]
      (thi.ng.geom.types.Plane. n (g/dot n p))))

  (defn plane-from-points
    ([[a b c]] (plane-from-points a b c))
    ([a b c]
       (let [n (gu/ortho-normal a b c)]
         (thi.ng.geom.types.Plane. n (g/dot n a)))))
#+END_SRC
** Helper functions
#+BEGIN_SRC clojure :noweb-ref helpers
  (defn intersect-plane
    [an aw bn bw]
    (when-not (or (m/delta= aw bw *eps*) (m/delta= an bn *eps*))
      (let [od (g/dot an bn)
            det (/ (mm/madd od od -1))
            u (* (mm/madd bw od (- aw)) det)
            v (* (mm/madd aw od (- bw)) det)]
        {:p (g/madd an u (g/* bn v)) :dir (g/normalize (g/cross an bn))})))
#+END_SRC
** TODO Protocol implementation
#+BEGIN_SRC clojure :noweb-ref impl
  (extend-type thi.ng.geom.types.Plane
#+END_SRC
*** PCenter
#+BEGIN_SRC clojure :noweb-ref impl
  g/PCenter
  (center
    ([_] (thi.ng.geom.types.Plane. (:n _) 0))
    ([_ o] (plane-with-p o (:n _))))
  (centroid
    ([_] (g/* (:n _) (:w _))))
#+END_SRC
*** PClassify
#+BEGIN_SRC clojure :noweb-ref impl
  g/PClassify
  (classify-point
    [_ p]
    (-> (:n _) (g/dot p) (- (:w _)) (m/signum *eps*)))
#+END_SRC
*** PDistance
#+BEGIN_SRC clojure :noweb-ref impl
  g/PDistance
  (dist
   [_ p] (->> p (g/dot (:n _)) (+ (- (:w _)))))
  (dist-squared
   [_ p] (let [d (g/dist _ p)] (* d d)))
#+END_SRC
*** PFlip
#+BEGIN_SRC clojure :noweb-ref impl
  g/PFlip
  (flip
    [_] (thi.ng.geom.types.Plane. (g/- (:n _)) (- (:w _))))
#+END_SRC
*** PIntersect
#+BEGIN_SRC clojure :noweb-ref impl
  g/PIntersect
  (intersect-line
   ([_ line] (g/intersect-ray _ (:p line) (g/- (:q line) (:p line))))
   ([_ p q] (g/intersect-ray _ p (g/- q p))))
  (intersect-ray
   ([_ ray] (g/intersect-ray _ (:p ray) (:dir ray)))
   ([_ p dir]
      (let [dp (g/dot (:n _) dir)
            dn (- (g/dot (:n _) p) (:w _))]
        (if (m/delta= 0.0 dp *eps*)
          {:type (if (zero? dn) :on-plane :parallel)}
          (let [du (- (/ dn dp))
                i (g/madd dir du p)]
            (if (m/in-range? 0.0 1.0 du)
              {:type :intersect :p i}
              {:type :intersect-outside :p i}))))))
  (intersect-shape
   [_ s]
   (cond
    (instance? thi.ng.geom.types.Plane s) (intersect-plane (:n _) (:w _) (:n s) (:w s))
    :default (err/illegal-arg! s)))
#+END_SRC
*** PMeshConvert
#+BEGIN_SRC clojure :noweb-ref impl
  g/PMeshConvert
  (as-mesh
   ([_] (g/as-mesh _ {}))
   ([_ {:keys [p width height size] :or {size 1.0}}]
      (let [w (* (or width size) 0.5)
            h (* (or height size) 0.5)
            flip? (m/delta= -1.0 (g/dot (:n _) v/V3Z))
            p (g/closest-point _ (or p (vec3)))
            q (if flip?
                (q/quat 0 0 0 1)
                (q/alignment-quat v/V3Z (:n _)))
            [a b c d] (map #(g/+ p (g/transform-vector q %))
                           [(vec3 (- w) (- h) 0) (vec3 (- w) h 0)
                            (vec3 w h 0) (vec3 w (- h) 0)])]
        (gm/add-face (gm/gmesh) (if flip? [a b c d] [d c b a])))))
#+END_SRC
*** PProximity
#+BEGIN_SRC clojure :noweb-ref impl
  g/PProximity
  (closest-point
    [_ p]
    (->> p
         (g/dot (:n _))
         (+ (- (:w _)))
         (g/normalize (:n _))
         (g/- p)))
#+END_SRC
*** End implementation                                             :noexport:
#+BEGIN_SRC clojure :noweb-ref impl
  )
#+END_SRC
** Namespace declaration
#+BEGIN_SRC clojure :tangle ../babel/src/cljx/thi/ng/geom/plane.cljx :noweb yes :mkdirp yes :padline no
  (ns thi.ng.geom.plane
    ,#+cljs (:require-macros [thi.ng.macromath.core :as mm])
    (:require
     [thi.ng.geom.core :as g]
     [thi.ng.geom.core.utils :as gu]
     [thi.ng.geom.core.vector :as v :refer [vec3]]
     [thi.ng.geom.core.quaternion :as q]
     [thi.ng.geom.gmesh :as gm]
     [thi.ng.geom.types :as types]
     [thi.ng.geom.types.utils :as tu]
     [thi.ng.common.error :as err]
     [thi.ng.common.math.core :as m :refer [*eps*]]
     ,#+clj [thi.ng.macromath.core :as mm])
    ,#+clj
    (:import
     [thi.ng.geom.types Plane]))

  <<ctors>>

  <<helpers>>

  <<impl>>
#+END_SRC<commit_msg>add more protocol impls for Plane, bugfix intersect impl for new line types, rename plane-with-p ctor<commit_after>#+SETUPFILE: ../../src/setup.org

* thi.ng.geom.plane

** Constructor
#+BEGIN_SRC clojure :noweb-ref ctors
  (defn plane
    [n w] (thi.ng.geom.types.Plane. (g/normalize (vec3 n)) w))

  (defn plane-with-point
    [p n]
    (let [n (g/normalize (vec3 n))]
      (thi.ng.geom.types.Plane. n (g/dot n p))))

  (defn plane-from-points
    ([[a b c]] (plane-from-points a b c))
    ([a b c]
       (let [n (gu/ortho-normal a b c)]
         (thi.ng.geom.types.Plane. n (g/dot n a)))))
#+END_SRC
** Helper functions
#+BEGIN_SRC clojure :noweb-ref helpers
  (defn intersect-plane
    [an aw bn bw]
    (when-not (or (m/delta= aw bw *eps*) (m/delta= an bn *eps*))
      (let [od (g/dot an bn)
            det (/ (mm/madd od od -1))
            u (* (mm/madd bw od (- aw)) det)
            v (* (mm/madd aw od (- bw)) det)]
        {:p (g/madd an u (g/* bn v)) :dir (g/normalize (g/cross an bn))})))
#+END_SRC
** TODO Protocol implementation
#+BEGIN_SRC clojure :noweb-ref impl
  (extend-type thi.ng.geom.types.Plane
#+END_SRC
*** PArea
#+BEGIN_SRC clojure :noweb-ref impl
  g/PArea
  (area [_] INF+)
#+END_SRC
*** PBounds
#+BEGIN_SRC clojure :noweb-ref impl
  g/PBounds
  (bounds
   [_]
   (let [s (vec3 (g/width _) (g/height _) (g/depth _))]
     (thi.ng.geom.types.AABB. (g/madd s -0.5 (g/centroid _)) s)))
  (width
   [_] (if (m/delta= (g/abs (:n _)) v/V3X *eps*) 0.0 INF+))
  (height
   [_] (if (m/delta= (g/abs (:n _)) v/V3Y *eps*) 0.0 INF+))
  (depth
   [_] (if (m/delta= (g/abs (:n _)) v/V3Z *eps*) 0.0 INF+))
#+END_SRC
*** PBoundingSphere
#+BEGIN_SRC clojure :noweb-ref impl
  g/PBoundingSphere
  (bounding-sphere
    [_] (thi.ng.geom.types.Sphere. (g/centroid _) INF+))
#+END_SRC
*** PCenter
#+BEGIN_SRC clojure :noweb-ref impl
  g/PCenter
  (center
    ([_] (thi.ng.geom.types.Plane. (:n _) 0))
    ([_ o] (plane-with-point o (:n _))))
  (centroid
    ([_] (g/* (:n _) (:w _))))
#+END_SRC
*** PClassify
#+BEGIN_SRC clojure :noweb-ref impl
  g/PClassify
  (classify-point
    [_ p]
    (-> (:n _) (g/dot p) (- (:w _)) (m/signum *eps*)))
#+END_SRC
*** PDistance
#+BEGIN_SRC clojure :noweb-ref impl
  g/PDistance
  (dist
   [_ p] (->> p (g/dot (:n _)) (+ (- (:w _)))))
  (dist-squared
   [_ p] (let [d (g/dist _ p)] (* d d)))
#+END_SRC
*** PFlip
#+BEGIN_SRC clojure :noweb-ref impl
  g/PFlip
  (flip
    [_] (thi.ng.geom.types.Plane. (g/- (:n _)) (- (:w _))))
#+END_SRC
*** PIntersect
#+BEGIN_SRC clojure :noweb-ref impl
  g/PIntersect
  (intersect-line
   ([_ {[p q] :points}] (g/intersect-ray _ p (g/- q p)))
   ([_ p q] (g/intersect-ray _ p (g/- q p))))
  (intersect-ray
   ([_ ray] (g/intersect-ray _ (:p ray) (:dir ray)))
   ([_ p dir]
      (let [dp (g/dot (:n _) dir)
            dn (- (g/dot (:n _) p) (:w _))]
        (if (m/delta= 0.0 dp *eps*)
          {:type (if (zero? dn) :on-plane :parallel)}
          (let [du (- (/ dn dp))
                i (g/madd dir du p)]
            (if (m/in-range? 0.0 1.0 du)
              {:type :intersect :p i}
              {:type :intersect-outside :p i}))))))
  (intersect-shape
   [_ s]
   (cond
    (instance? thi.ng.geom.types.Plane s) (intersect-plane (:n _) (:w _) (:n s) (:w s))
    :default (err/illegal-arg! s)))
#+END_SRC
*** PMeshConvert
#+BEGIN_SRC clojure :noweb-ref impl
  g/PMeshConvert
  (as-mesh
   ([_] (g/as-mesh _ {}))
   ([_ {:keys [p width height size] :or {size 1.0}}]
      (let [w (* (or width size) 0.5)
            h (* (or height size) 0.5)
            flip? (m/delta= -1.0 (g/dot (:n _) v/V3Z))
            p (g/closest-point _ (or p (vec3)))
            q (if flip?
                (q/quat 0 0 0 1)
                (q/alignment-quat v/V3Z (:n _)))
            [a b c d] (map #(g/+ p (g/transform-vector q %))
                           [(vec3 (- w) (- h) 0) (vec3 (- w) h 0)
                            (vec3 w h 0) (vec3 w (- h) 0)])]
        (gm/add-face (gm/gmesh) (if flip? [a b c d] [d c b a])))))
#+END_SRC
*** PProximity
#+BEGIN_SRC clojure :noweb-ref impl
  g/PProximity
  (closest-point
    [_ p]
    (->> p
         (g/dot (:n _))
         (+ (- (:w _)))
         (g/normalize (:n _))
         (g/- p)))
#+END_SRC
*** PTransform
#+BEGIN_SRC clojure :noweb-ref impl
  g/PScale
  (scale
   ([_ s] (plane-with-point (g/* (g/centroid _) s) (:n _)))
   ([_ a b] (plane-with-point (g/* (g/centroid _) a b) (:n _)))
   ([_ a b c] (plane-with-point (g/* (g/centroid _) a b c) (:n _))))
  (scale-size
   ([_ s] _))
  g/PTranslate
  (translate
   [_ t] (plane-with-point (g/+ (g/centroid _) t) (:n _)))
  g/PTransform
  (transform
   [_ m] (plane-with-point
          (g/transform-vector m (g/centroid _))
          (g/transform-vector m (:n _))))
#+END_SRC
*** PVolume
#+BEGIN_SRC clojure :noweb-ref impl :noweb yes
  <<lob-geom-zerovol>>
#+END_SRC

*** End implementation                                             :noexport:
#+BEGIN_SRC clojure :noweb-ref impl
  )
#+END_SRC
** Namespace declaration
#+BEGIN_SRC clojure :tangle ../babel/src/cljx/thi/ng/geom/plane.cljx :noweb yes :mkdirp yes :padline no
  (ns thi.ng.geom.plane
    ,#+cljs (:require-macros [thi.ng.macromath.core :as mm])
    (:require
     [thi.ng.geom.core :as g]
     [thi.ng.geom.core.utils :as gu]
     [thi.ng.geom.core.vector :as v :refer [vec3]]
     [thi.ng.geom.core.quaternion :as q]
     [thi.ng.geom.gmesh :as gm]
     [thi.ng.geom.types :as types]
     [thi.ng.geom.types.utils :as tu]
     [thi.ng.common.error :as err]
     [thi.ng.common.math.core :as m :refer [*eps* INF+]]
     ,#+clj [thi.ng.macromath.core :as mm])
    ,#+clj
    (:import
     [thi.ng.geom.types Plane]))

  <<ctors>>

  <<helpers>>

  <<impl>>
#+END_SRC
{'fraction_non_alphanumeric': 0.20330875024915288, 'fraction_numerical': 0.007972892166633447, 'mean_word_length': 2.170616113744076, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '84579', 'n_tokens_mistral': 4535, 'n_tokens_neox': 4267, 'n_words': 1054}