Writing conditions on geometric coordinates

2011-05-28 Thread Brian Watkins
I often write code that deals with geometric coordinates and similar
ordered n-tuples on homogenous bases.  Lots of times I face the
situation where I want to write a condition that says, "if these two
regions overlap, then do something," or "if this function is satisfied
over an axis ax+by=c or over an axis bx+ay=c then do something."

The issue is that the x and y (and z and z' ... ) coordinates are
often interchangeable and the condition needs to be satisfied over any
one of them or all of them.

Here, for instance, is a check that two rectangles, rect-one and rect-
two, with corners [:x0 :y0] and [:x1 :y1] overlap.  This is vastly
simplified, of course.  I'm sure you can imagine that when the
combinations of axes and desired conditions become more and more
complex, the code gets more and more repetitive and awful.

(and
  (>= (rect-one :x1) (rect-two :x0))
  (>= (rect-two :x1) (rect-one :x0))
  (>= (rect-one :y1) (rect-two :y0))
  (>= (rect-two :y1) (rect-one :y0)))


Problem is that code is awful and repetitive.  I can shrink it in
various one-off ways but I wonder if anyone has general advice or
experience in writing a readable condition function.  I think it
should be reduced with multiple axes substituted into a function
somehow but I don't know a good idiom to make it clear.

Maybe an experienced lisper or wise code craftsman can help me out.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Writing conditions on geometric coordinates

2011-05-29 Thread Andreas Liljeqvist
Not sure if I understand your problem.

Is it the verbosity of extracting coordinates? (rect-one :x1)

Or is the problem with increasing the dimensionality?

Anyhow I would define the types as following:

(def point [1 2 3])
(def rect [point point])

(defn point-in-rect? [p [[r1 r2]]]
  (every? true? (map <= r1 p r2)))

(defn overlap-rect? [a b]
  (or (some #(point-in-rect % a) b)
  (some #(point-in-rect % b) a)))

this should work for n-dimensions I think.

If you want to more closely follow your original code:

(with-destructured-rects rect-one rect-two
  (and
(>= r1x1 r2x0)
(>= r2x1 r1x0)))




2011/5/29 Brian Watkins 

> I often write code that deals with geometric coordinates and similar
> ordered n-tuples on homogenous bases.  Lots of times I face the
> situation where I want to write a condition that says, "if these two
> regions overlap, then do something," or "if this function is satisfied
> over an axis ax+by=c or over an axis bx+ay=c then do something."
>
> The issue is that the x and y (and z and z' ... ) coordinates are
> often interchangeable and the condition needs to be satisfied over any
> one of them or all of them.
>
> Here, for instance, is a check that two rectangles, rect-one and rect-
> two, with corners [:x0 :y0] and [:x1 :y1] overlap.  This is vastly
> simplified, of course.  I'm sure you can imagine that when the
> combinations of axes and desired conditions become more and more
> complex, the code gets more and more repetitive and awful.
>
> (and
>  (>= (rect-one :x1) (rect-two :x0))
>  (>= (rect-two :x1) (rect-one :x0))
>  (>= (rect-one :y1) (rect-two :y0))
>  (>= (rect-two :y1) (rect-one :y0)))
>
>
> Problem is that code is awful and repetitive.  I can shrink it in
> various one-off ways but I wonder if anyone has general advice or
> experience in writing a readable condition function.  I think it
> should be reduced with multiple axes substituted into a function
> somehow but I don't know a good idiom to make it clear.
>
> Maybe an experienced lisper or wise code craftsman can help me out.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en