Page 1 of 1

Dropouts at certain angles when rotating a path

Posted: 2012-09-06T06:07:36-07:00
by whugemann
I try to draw a hexagon with ImageMagick. This is done by a DOS batch file which generates the command and shall do this not only for hexagons, but also for regular polygons with abitrary corner point count (in the future). I dumped the output of my batch into a textfile:

Code: Select all

Convert -size 2592x1994 xc:white -strokewidth 10 -stroke black -draw "translate 1000,900         rotate 0 Path 'M 600,0 600,200' rotate 60 Path 'M 600,0 600,200' rotate 120 Path 'M 600,0 600,200' rotate 180 Path 'M 600,0 600,200' rotate 240 Path 'M 600,0 600,200' rotate 300 Path 'M 600,0 600,200' rotate 360 Path 'M 600,0 600,200'" Test.png
This Convert command does however leave out the lines with 120° and 300°rotation. What's going wrong over here? (Besides the fact that this "hexagon" is far from perfect ...)

Re: Dropouts at certain angles when rotating a path

Posted: 2012-09-06T17:06:26-07:00
by anthony
Hmmm replacing 120, with 125 and I see the line.. just off one of the other lines.

the problem is that rotate and other transforms are incrementally added to the draw affine matrix (multiplied to one matrix). As such doing what you did results in angles
rotate 0 -- 0
rotate 60 -- 60
rotate 120 -- 180
rotate 180 -- 360, or 0 (overwrite)
rotate 240 -- 240
rotate 300 -- 540 or 180 (overwrite)

So what appeared to be missing is 120 and 300 are actually drawn, but on top of something else.

Solution use graphic contexts to save and restore the state (affine wrapping matrix).
See Push and Pop Context
http://www.imagemagick.org/Usage/draw/#push_context

Code: Select all

convert -size 2592x1994 xc:white -strokewidth 10 -stroke black -draw "\
      translate 1000,900
      push graphic-context rotate 0   Path 'M 600,0 600,200' pop graphic-context
      push graphic-context rotate 60  Path 'M 600,0 600,200' pop graphic-context
      push graphic-context rotate 120 Path 'M 600,0 600,200' pop graphic-context
      push graphic-context rotate 180 Path 'M 600,0 600,200' pop graphic-context
      push graphic-context rotate 240 Path 'M 600,0 600,200' pop graphic-context
      push graphic-context rotate 300 Path 'M 600,0 600,200' pop graphic-context
    " test.png
Which keeps the translation, but removes the rotation additions to the translation matirx

OR this whcih is increment rotations

Code: Select all

convert -size 2592x1994 xc:white -strokewidth 10 -stroke black -draw "\
      translate 1000,900   Path 'M 600,0 600,200'
      rotate 60                 Path 'M 600,0 600,200'
      rotate 60                 Path 'M 600,0 600,200'
      rotate 60                 Path 'M 600,0 600,200'
      rotate 60                 Path 'M 600,0 600,200'
      rotate 60                 Path 'M 600,0 600,200'
    " test.png
OR this which uses a affine setting to set the translation outside draw, (and imported by draw) and then does the rotation inside draw.

Code: Select all

convert -size 2592x1994 xc:white -strokewidth 10 -stroke black \
         -affine '1,0,0,1,1000,900' -draw "Path 'M 600,0 600,200'" \
         -draw "rotate 60  Path 'M 600,0 600,200'" \
         -draw "rotate 120  Path 'M 600,0 600,200'" \
         -draw "rotate 180  Path 'M 600,0 600,200'" \
         -draw "rotate 240  Path 'M 600,0 600,200'" \
         -draw "rotate 300  Path 'M 600,0 600,200'" \
         test.png
Take your pick. The latter is probably slower, (and a bit faster in IMv7 magick, but still slower than the other two).
I have not done any timing tests, though canvas generation and I/O probably still take up more time than the actual draw.

Re: Dropouts at certain angles when rotating a path

Posted: 2012-09-06T17:08:26-07:00
by anthony
You can see a more practical demonstration of the graphic context in 'arrow drawing'
http://www.imagemagick.org/Usage/draw/#arrows

Re: Dropouts at certain angles when rotating a path

Posted: 2012-09-06T23:25:26-07:00
by whugemann
Thanks Anthony,

the basic idea that I missed is that the rotations are incremental. I made the same mistake in the thread viewtopic.php?f=1&t=21752, rotating by
  • 90°
  • 90° + 180° = 270°
  • 90° + 180° + 270° = 180°
which however didn't reveal, as the result turned out as expected.