Geometry puzzler

Paul Winkler slinkp23 at yahoo.com
Sun Nov 5 21:55:35 EST 2000


I have a problem that's more geometry than python per se, but I need a
solution in python so I thought I'd ask here. This is for a
proprietary web application I'm developing, but I'd be happy to donate
this part of my code to the python community - probably in the form of
some example code for sping (formerly known as PIDDLE... see
sping.sourceforge.net) since that's what I'm using. I just don't know
enough geometry to work this one out on my own...

I need to draw text on a page without it overlapping with various
other graphic elements on the page. Problem is that those elements
could be anywhere, so I need a general solution. This would be useful
for vector-drawing and page layout applications in general.

One way I thought of is to keep track of one or more allowed drawing
zones on my canvas. These zones could be represented as polygons
defined by a sequence of (x,y) coordinate tuples. We can find the
perimeter of such a polygon by drawing line segments between each
coordinate pair in the sequence, and then one line from the last
coordinate pair to the first to close the polygon. So far so good.
So:

( (0,0), (100,0), (100,100), (0, 100) )

...would be a square.


There are two basic but important things I can't figure out how to do:

1) Given any polygon, how can I test whether an arbitrary point lies
   inside that polygon?

2) Given two line segments, how can I find the coordinates of their
   intersection, if there is one? (easy for right angles, but I will
   often NOT have right angles.)


I think if I knew how to do those two things, I could work out how to
effectively manage and use an allowable drawing zone. For any line of
text I could find the edges where it runs out of the allowed zone.
Then whenever I added one of my graphic elements to the page, I could
draw a polygon around it and subtract that space from the allowed
zone.

So my real problem, which I think I could solve given 1 and 2 above,
is to combine such polygons in various ways.

I need two functions or methods so that:

bite(poly1, poly2) returns a new polygon which looks like poly1 with
   the area encompassed by poly2 removed from it.

union(poly1, poly2) returns a new polygon which looks like poly1 with
   the area encompassed by poly2 added to it.


Examples in ugly ASCII art - two simple intersecting polygons.


1 represents poly1, 2 represents poly2.


 1111111111111111111111111
 1    	       	       	 1
  1 		   22222+222222
  1		   2   	1      2
   1 		   2   1        2
   1 		   2   1         2
    1 		   222+222222222222
    1 	       	      1
     1	       	     1
     11111111111111111


union(1,2) would look like:



 1111111111111111111111111
 1		       	 1
  1 		        +222222
  1		       	       2
   1 		                2
   1		                 2
    1 		      +222222222222
    1 	       	      1
     1	       	     1
     11111111111111111


bite(1,2) would look like:

 1111111111111111111111111
 1		       	 1
  1 		   22222+
  1		   2
   1 		   2
   1		   2
    1 		   222+
    1 	       	      1
     1	       	     1
     11111111111111111



 
 Now that I've got this 
  shape defined I can 
  draw my text inside
   it nicely just
   by inserting
    line breaks anytime
    I'm about to go  
     out of bounds  
     for this line.

 
Of course there are many different ways polygons can intersect,
and I can't think of a solution for all cases. I don't even know 
what to do when one polygon is entirely inside the other.
(obvious for union, non-obvious for bite!)

-- 
.................    paul winkler    ..................
slinkP arts:   music, sound, illustration, design, etc.
           web page:  http://www.slinkp.com
      A member of ARMS:   http://www.reacharms.com



More information about the Python-list mailing list