JS / Clojure (или любой другой) код для преобразования полярных координат в декартовы координаты на (тангенциальном?) Правильном прямоугольнике? - PullRequest
0 голосов
/ 04 августа 2020

Это JS / Clojure-код для преобразования полярных координат в декартовы? Учитывая угол в полярных координатах, я хочу понять его декартовы координаты на произвольном (тангенциальном?) Прямоугольнике (на его сторонах).

Я могу примерно представить решение, поэтому я спрашиваю, видели ли вы код, а не руководство :)

график

Ответы [ 2 ]

2 голосов
/ 04 августа 2020
(use
    '[incanter core stats charts io])
(require
    '[thi.ng.geom.line :as l]
    '[thi.ng.geom.utils.intersect]
    '[thi.ng.geom.circle]
    '[thi.ng.geom.polygon :as p]
    '[thi.ng.geom.rect :as r]
    '[thi.ng.geom.core :as g])


(let [R      7
      S      (* 2 R)
      p1     [[R R] [(- R) R] [(- R) (- R)] [R (- R)]]
      r1     (r/rect (- R) (- R) S S)

      circle (fn [c] (fn [t] [(* (:r c) (cos t)) (* (:r c) (sin t))]))
      c1     (g/bounding-circle (p/polygon2 p1))
      c2     (g/scale-size c1 0.7)
      x      3
      y      (Math/sqrt (- (* R R) (* x x)))
      l1     (l/line2 0 0 x y)
      l2     (g/scale l1 2)
      [x' y'] (g/intersect-line r1 l2)]

    (doto (xy-plot [-10 10] [-10 10])
        (set-theme-bw )
        (add-parametric (circle c2) (- Math/PI) Math/PI)
        (add-polygon (:points (g/as-polygon r1)))
        (add-points x y)
        (add-polygon (:points l1))
        (add-points x' y')
        (set-stroke :width 3 :dash 5)
        (set-stroke-color java.awt.Color/gray)
        view))

диаграмма

PS много кода только для картинки. На самом деле вам нужно только g/intersect-line.

1 голос
/ 05 августа 2020

Если бы мы знали, что прямоугольник будет квадратом с центром вокруг начала координат, тогда было бы компактное решение. Для более общего случая, о котором вы просите, вот возможное решение:

(defn rect-edges
  "Construct the four edges of the rect"
  [x y width height]
  [[1 0 x]
   [1 0 (+ x width)]
   [0 1 y]
   [0 1 (+ y height)]])

(def min-vec (completing (comp first sort vector)))

(defn intersect-dir
  "Intersect a ray from the origin with a line"
  [[dx dy] [nx ny k]]
  (let [dot (+ (* nx dx) (* ny dy))]
    (if (not (zero? dot))
      (let [lambda (/ k dot)]
        (if (<= 0 lambda)
          [lambda (* lambda dx) (* lambda dy)])))))

(defn boundary-intersection
  "Find the point that intersects the boundary of a polygon"
  [dir boundary-edges]
  (rest (transduce
         (comp (map (partial intersect-dir dir))
               (filter some?))
         min-vec
         [Double/POSITIVE_INFINITY 0 0]
         boundary-edges)))

(defn polar-to-cartesian-rect [alpha rho edges]
  (boundary-intersection [(* rho (Math/cos alpha))
                          (* rho (Math/sin alpha))]
                         edges))

Пример его вызова:

(let [rho 1
      rect (rect-edges -2 -3 5 4)]
  (doseq [alpha-deg [0 30 60 90 120 150 180 210 -90]]
    (println "Intersection at angle alpha =" alpha-deg "is"
             (polar-to-cartesian-rect (Math/toRadians alpha-deg)
                                      rho rect))))

и мы получаем

Intersection at angle alpha = 0 is (3.0 0.0)
Intersection at angle alpha = 30 is (1.7320508075688779 1.0)
Intersection at angle alpha = 60 is (0.577350269189626 1.0)
Intersection at angle alpha = 90 is (6.123233995736766E-17 1.0)
Intersection at angle alpha = 120 is (-0.5773502691896255 1.0)
Intersection at angle alpha = 150 is (-1.7320508075688779 1.0)
Intersection at angle alpha = 180 is (-2.0 2.4492935982947064E-16)
Intersection at angle alpha = 210 is (-2.0 -1.154700538379252)
Intersection at angle alpha = -90 is (1.8369701987210297E-16 -3.0)
...