[diagrams] Transforms that do not preserve angles.

Ryan Yates fryguybob at gmail.com
Wed Jun 16 19:12:15 EDT 2010

Hi All,

I thought I would share some truly ugly code that makes bounds work
correctly (only in the 2D case) with transforms that do not preserve angles.
 The idea behind this is that what we really want is to preserve the
orientation of the bounding hyperplane through transformations, not the
orientation of the vector given to the bounds function.  In the 2D case the
"orientation" is the perpendicular.  Using decompose and recompose I can
find the perpendicular that I want to preserve "generically" (but really
just dirty hack doing the 2D case).  This is p in the code below.  I can
then transform the perpendicular vector (p') and user that to find the
vector that when passed to the bounds function (b) would give the
angle preserved result.

For the 3D case if we have scaling along a vector u, then I believe treating
the plane formed by u--v (v being our bounds parameter) in the same way as
the 2D case would give the correct result.  I don't know how that works out
for transforms in general.  Perhaps some more information needs to be
retained with each transform that tells us how to preserve orthogonality?
 Anyway I don't know if this helps get things any closer, but thought I
would share.


hunk ./src/Graphics/Rendering/Diagrams/Basics.hs 211
-              -- XXX this is still wrong for transformations that don't
preserve angle!
-              (Bounds $ b . apply (inv t))
+              -- XXX this is still wrong for anything but 2D!
+              (Bounds $ tfmG t b)
hunk ./src/Graphics/Rendering/Diagrams/Basics.hs 215
+perpG :: (HasBasis v, Num (Scalar v)) => v -> v
+perpG v = recompose bs'
+  where bs = decompose v
+        a  = head bs
+        b  = (head . tail) bs
+        a' = (fst a, snd b)
+        b' = (fst b, -(snd a))
+        bs' = [a',b']++(tail . tail $ bs)
+tfmG t b v = let  p   = normalized (perpG v)
+                  p'  = apply (inv t) p
+                  v'  = apply (inv t) v
+                  u'  = normalized v'
+                  pp' = zeroV ^-^ (normalized . perpG) p'
+                  sp' = b pp'
+                  s'  = sp'/ (u' <.> pp')
+                  r   = apply t (u' ^* s')
+                  s   = magnitude r
+              in  s
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.haskell.org/pipermail/diagrams/attachments/20100616/eccecd58/attachment.htm 

More information about the diagrams mailing list