A blog on math

August 30, 2009

Quick Heuristic For Tangram Polygon Intersection

Filed under: Computational Geometry — Bryan Bell @ 8:39 am
Tags: , , , ,

For the combinatorial approach to solving Tangram puzzles one frequent operation is to test if a puzzle piece, p, is contained in the silhouette s. Before this test is made the puzzle piece, p, is translated to a vertex, v, of s and one of the edges of p is aligned with an edge, e, coming out of vertex v.

For clarity I’ve included a figure below illustrating this.

puzzle piece and silhouette

In the above figure it’s obvious that the puzzle piece, p, does not fit in the silhouette. One way to see this computationally is to look at the edge, e, and notice that at vertex, v_1, the next edge of the silhouette, s, makes a left turn with respect to the edge e. This means that if the length of e is less than the length of all the edges in p then there is no possible way to fit p in s. That is as long as we have the condition that one of the edges of p is aligned with the edge e of s.

The above statement provides a quick way to skip vertices of the silhouette s when trying to fit the puzzle piece p in the silhouette s. Of course before skipping the vertex the same test needs to be done on the other edge coming out of v. Also we note that the above test only works if the next edge coming out of v_1 makes a left turn with respect to the edge e, otherwise the full test for polygon intersection has to be run. Also if one of the edges of the puzzle piece p has length less than or equal to the length of e then the full test for polygon intersection has to be run.

In summary this is a very specific heuristic that in general isn’t very useful but if you ever find yourself needing it, it can be just what the doctor ordered.

August 20, 2009

A Heuristic Solution to the Tangram Puzzle

Filed under: Computational Geometry — Bryan Bell @ 9:44 pm
Tags: , , ,

In this post I present a short summary of the paper “A Heuristic Solution to the Tangram Puzzle” by E.S. Deutsch and K. C. Hayes Jr. I’ve uploaded a scanned copy of the paper to scribd here. Uploading the scanned copy probably violates some copyright law so if they or anyone else contacts me I’ll remove the document. Ironically it’s taken me over two-years since my post here to finally read the paper.

In their paper they talk about two possible approaches to solving tangrams. One is the combinatorial approach that I’ve taken and the other is the heuristic method that they describe in their paper. The heuristic method that they use is a little clever, what they do is take the outline of the tangram puzzle and then try to break it out into sub-puzzles. The following figure illustrates where two puzzles have both been separated out into sub-puzzles. In both cases one of the sub-puzzles exactly matches a tangram piece thus allowing the algorithm to solve that sub-puzzle.

Puzzle Illustration

The dashed lines in the figure show where the algorithm is splitting the sub-puzzles out from the original puzzle. First note that the dashed lines are called “extension lines” in the paper. They are generated to allow the extraction of the sub-puzzles. To create the extension lines the algorithm goes along the outline of the puzzle and at convex corners it generates an “extension line” that allows the possible separation of the puzzle into sub-puzzles. The following figure illustrates this. In the paper they outline various ways for eliminating extension lines that are unlikely to be of use.

Extension Lines

Once the above extension lines are created there is a set of heuristics for splitting out sub-puzzles, the heuristics are used in the following order.


1. direct-match rule

The algorithm attempts to locate puzzle pieces fully described by edges, rather than by extension lines or by combinations of edges and extension lines.

2. 2 1/2 – 3 1/2 edge-match rule
The direct-match rule while being very reliable in finding matches cannot be used in most cases this means that a more relaxed rule is needed. The 2 1/2 – 3 1/2 edge-match rule allows the location of puzzle pieces where most of the periphery is described by edges and a small portion is described by extension lines. Specifically the “2 1/2 – 3 1/2 edge-match rules requires that in the case of triangular shapes two complete sides must be defined by edges and the remaining side can be defined by a combination of collinear edges and extension lines. Moreover, the combination must include at least one portion of edge. For four sided puzzle pieces the rule requires that the additional side also be fully described by an edge.” [1]

There are an additional 8 extraction rules that are used but the above two give you their general flavor.

The organization of the extraction rules is to run them recursively and at each step try to apply the most specific one possible first. If the algorithm gets to a step where there are no possible extractions it backtracks and tries another extraction rule. This process is not guaranteed to find a solution and in fact the paper gives an example of a puzzle on page 239 for which no solution is found.

The paper is a niece example of where a little clever thinking and some very specific heuristics can solve tangram puzzles.

References

[1] Deutsch, E. S., and K. C. Hayes Jr. “A Heuristic Solution to the Tangram Puzzle”, Machine Intelligence vol. 7, 1972, p. 205–240.

June 4, 2009

Convex Hulls

The algorithm I’m going to showcase is taken from the book “Computational Geometry algorithms and applications” by Berg, Cheong, Kreveld, and Overmars. They give an excellent analysis of the algorithm in the book so I’ll only go over the highlights and show my implementation in Javascript using the html5 canvas.

The problem statement is given a set of points, S = \{p_1, p_2, \ldots, p_n\} in R^2 compute the convex hull of S. The input of the algorithm is the set, S, of points and the output of the algorithm is the set of points that are the vertices of the convex hull of S.

Our algorithm will use a standard design technique to generate what’s called an incremental algorithm. That is we compute the solution for the first p_1, \ldots, p_i points then add the point p_{i+1} and compute the new solution using the previous solution.

Algorithm ConvexHull(P) (the pseudocode is borrowed from “Computational Geometry algorithms and applications”)
Input. A set P of points in the plane
Output. A list containing the vertices of \mathcal{CH}(P) in clockwise order.
1. Sort the points by x-coordinate, resulting in a sequence p_1,\ldots, p_n.
2. Put the points p_1 and p_2 in a list \mathcal{L}_\textrm{upper}, with p_1 as the first point.
3. for i \leftarrow 3 to n
4.        do Append p_i to \mathcal{L}_\textrm{upper}.
5.                        while \mathcal{L}_\textrm{upper} contains more than two points and the last three points in \mathcal{L}_\textrm{upper} do not make a right turn
6.                           do Delete the middle of the last three points from \mathcal{L}_\textrm{upper}.
7. Put the points p_n and p_{n-1} in a list \mathcal{L}_\textrm{lower}, with p_n as the first point.
8. for i \leftarrow n -2 downto 1
9.           do Append p_i to \mathcal{L}_\textrm{lower}.
10.                     while \mathcal{L}_\textrm{lower} contains more than 2 points and the last three points in \mathcal{L}_\textrm{lower} do not make a right turn
11.                     do Delete the middle of the last three points from \mathcal{L}_\textrm{lower}.
12. Remove the first and last point from \mathcal{L}_\textrm{lower}. to ovoid duplication of the points where the upper and lower hull meet.
13. Append \mathcal{L}_\textrm{lower} to \mathcal{L}_\textrm{upper}, and call the resulting list \mathcal{L}.
14. return \mathcal{L}.

You can view an implementation using Javascript and the html5 canvas element, here. To add a new point simply click the left mouse button and it’ll add a point where the mouse is.

June 3, 2009

Right and Left Turns

In my previous post on line segment intersection I introduced the two dimensional cross product as v1 \times v2 = {v1}_x \cdot {v2}_y - {v2}_x \cdot {v1}_y. The cross product can also be used to determine if a set of three points p_1, p_2, \textrm{ and } p_3 make a right turn.

First note that if v_1 \times v_2 > 0 then the angle between v_1 and v_2 is strictly less than \pi. For example the two vectors (1, 0) \times (0, 1) = 1 \cdot 1 - 0 = 1 > 0. Similarly if v_1 \times v_2 < 0 then the angle between them is strictly greater than \pi. In the below image I've shown an example where the three points p_1, p_2, \textrm{ and } p_3 make a right turn.

Points p1, p2, p3 making a right turn

To mathematically determine if the points make a right turn we let v_1 = p_1 - p_2 \textrm{ and } v_2 = p_3 - p_2. Then taking the cross product of v_1 \textrm{ and } v_2, we have v_1 \times v_2 > 0 which implies that the angle between them is less than \pi that is they make a right turn.

This method for determining whether the points make a right or left turn is very useful for determining the convex hull of a set of points.

I’ve posted an example webpage, here, where using javascript the lines change color depending on whether the turn is to the right or the left. Please note that the page uses the html5 canvas element so it will not work in internet explorer 7, or 6.

May 29, 2009

Line Segment Intersection

We want to determine if two line segments s_1 and s_2 intersect and if they do intersect, the point of intersection. First we want to analyze the problem. There is an edge case that is difficult to analyze (case 5 in the below list).

  1. The segments are not parallel (easy)
  2. The segments are parallel and do not intersect (easy)
  3. The segments are collinear and do not intersect (easy)
  4. The segments are collinear and do intersect (easy)
  5. The segments are nearly parallel or nearly collinear (hard)

In this post I handle cases 1 through 4. I’ll leave the handling of case 5 for later posts.

For the problem setup let segment 1 be given by

s_1 = p + t \cdot r where 0 <= t <= 1 and p, r are 2d vectors, similarly let segment 2 be given by

s_2 = q + u \cdot s where 0 <= u <= 1 and q, s are 2d vectors.

This representation of the line segments yields a very natural method for computing their intersection.

Computing cross products is the heart of the algorithm for determining intersections. The two dimensional cross product of p_1 \times p_2 is given by

\textrm{det} \left( \begin{array} {cc} x_1 & x_2 \\ y_1 & y_2\end{array} \right) = x_1y_2 - x_2y_1 = -p_2 \times p_1

If the cross product is zero then the two vectors are collinear that is pointing in either same direction or opposite directions.

The two lines intersect when p + t  \cdot r = q + u \cdot s, by crossing both sides with s we get

(p + t \cdot r) \times s = (q + u \cdot s) \times s = q \times s + u \cdot s \times s = q \times s.

From this we solve for t obtaining

t = \frac{(q - p) \times s}{r \times s}.

We can similarly solve for u, obtaining

u = \frac{(q -p) \times r}{r \times s}.

If both t and u are between 0 and 1, then the two line segments intersect and the intersection point is given by p + t \cdot r, where the value of t is the one we solved for. If either t or u are not between 0 and 1 then the line segments do not intersect.

But suppose r \times s = 0, then we can’t solve for t and u. This is because r \times s = 0 means that r and s are parallel which means the two line segments are parallel. Please also note that r \times s = 0 implies that r and s are scalar multiplies of each other. If (p -q) \times r \not= 0 then the segments are parallel but not collinear hence they do not intersect. If (p -q) \times r = 0 then the segments are collinear and we can simply project both of them onto to x-axis and determine if their projections intersect.

For case 5 when r \times s is close to zero the analysis needs to be well thought out and I’ll leave it to future posts.

I’ve posted a sample implementation in Javascript using the html5 canvas at http://cloud.github.com/downloads/bjwbell/canvas-geolib/main.html (please note it won’t work in internet explorer since it doesn’t support the canvas element).

Credit Gareth Rees for his post at stackoverflow.com which is based on the method for 3D line intersection algorithm from the article “Intersection of two lines in three-space” by Ronald Graham, published in Graphics Gems, page 304.

March 26, 2009

A Small Result in Polygon Translational Containment

Filed under: Computational Geometry — Bryan Bell @ 9:54 am
Tags: ,

Given two polygons P_1 and P_2 and two vectors t_1 and t_2 let P_1+t_1 and P_2 + t_2 be the vector sum. That is P_1 + t_1 is the set \{x \in \mathbb R^2 | x = a + t_1 \textrm{ where } a \in P_1\}. Also let the Minkowski sum of two sets A and B be as follows A \oplus B = \{a+b | a \in A, b \in B\}. The following lemma is on page 6 of the paper “Translational Polygon Containment and Minimal Enclosure using Mathematical Programming” by V.J. Milenkovic and Karen Daniels

The lemma is as follows: The set (P_1 + t_1)\cap(P_2 + t_2) is non-empty iff t_2 - t_1 \in P_1 \oplus - P_2.

To prove the lemma we note that t_2 - t_1 \in P_1\oplus -P_2 iff t_2 - t_1 = a - b for some a \in P_1 and b \in P_2. It then follows that b+t_2 = a+t_1 for some a \in P_1 and b \in P_2. Thus b+t_2 is a point in P_2 + t_2 and since b+t_2 = a + t_1 then b+t_2 is also a point in P_1 + t_1 hence b +t_2 is in (P_1 + t_1)\cap(P_2+t_2.

One question you might have is “what is the use of the lemma?”. The answer is that (P_1+t_1) does not intersect (P_2+t_2) iff t_2 - t_1 \in \overline{P_1 \oplus -P_2}. Thus given two translations of P_1 and P_2 we have an algorithm for deciding if the translated polygons overlap.

March 9, 2009

Solving Tangrams Using the Java Topology Suite (jts)

I’ve been using the Java Topology Suite (jts) to try and solve the Tangram puzzle. The basic algorithm is the same as I posted previously (it’s item 3 on the list of algorithms). The JTS is much easer to use and the source code is actually readable compared to CGAL. But on the downside JTS does not enforce rigorous geometry like CGAL does. This has some downsides mainly I had to modify the basic algorithm for shape fitting.

The main issue is that when trying to fit for example a triangle, t_1, inside another polygon say s_1. We can have roundoff errors such as in the following image.

round off error image

One slightly add-hoc way to solve this issue is to multiply t_1 by a scaling factor 1+\epsilon where epsilon is a small constant. Then when subtracting the new triangle (1+\epsilon)t_1 from s_1 we won’t have the issue of a small corner of s_1 being left over. But it does mean that we subtract slightly too much area from s_1. Which could cause an issue when we try to fit say another triangle, t_2, inside of s_2=s_1/(1+\epsilon)t_1 (e.g. t_2 won’t fit). To ensure t_2 fits what we can do is create a buffer of size #pieces \cdot \epsilon around s_2 before testing if t_2 is inside of s_2. Please note that #pieces is the number of for instance triangles we’re trying to fit inside of s_1 (so in this case #pieces = 2 since we’re trying to fit t_1 and t_2 inside of s_1). With the addition of the buffer even if s_2 is slightly too small the union of s_2 and its buffer will be large enough to cover t_2. I’ve had pretty good luck using this method with the JTS library.

You can see my code at the GitHub 2dfit site.

But a new problem is that solving the tangram puzzle takes a really long time since the algorithm goes through a large number of possible solutions before finding the correct one. Even after using the heuristic of fitting the largest shapes first the algorithm still takes a lot of time (in fact I’m still waiting for it to complete while writing this post). So I’ve been thinking of possible ways to speed up the algorithm. Below I’ve listed an algorithm that might be of some help in this.

Given two simple polygons called the silhouette and the puzzle piece. What we want is the algorithm to have two possible outcomes (1) it says “does not fit” in which case the puzzle piece cannot possible fit inside the silhouette and (2) “don’t know” in which case the puzzle piece could possible fit inside the silhouette but it’s also possible that it does not fit inside the silhouette.

In the below image I’ve shown the puzzle piece, p, which is a square and the silhouette, s, which is a simple polygon.

pieces

One way to determine that the puzzle piece, p, won’t fit is to start by constructing a bounding circle around it. As in the following figure.

bounding circle

What we do is calculate the %area of the circle filled by the puzzle piece (in this case a square). I’ve done the calculation and it’s \frac{2}{\pi}. Now suppose we wanted to test if the
square would not fit in the silhouette, s. Now also suppose that we try putting the bounding circle that we used for the square on the silhouette, s, as in the following figure.

bound circle 2

As is obvious the area of the bounding circle filled by the silhouette, s, is much less than \frac{2}{\pi}. Infact if we tried all possible placements of the bounding circle on the silhouette, s, we would find that the %area of the bounding circle filled by the silhouette is always less than \frac{2}{\pi}. This implies that the square cannot fit inside the silhouette, s. Now we need to determine what placements to use of the bounding circle to let us conclude that there is no possible placement that would give an %area of \frac{2}{\pi} filled by the silhouette s.

November 20, 2008

Reflection Symmetry

I’m interested in a method for determining if a simple polygon has reflection symmetry.

Let r denote reflection about the y-axis and \rho_\theta denote counter clockwise rotation by the angle \theta. Note that P has reflection symmetry iff r \rho_\theta P = P for some angle \theta. We also know r \rho_\theta = \rho_{-\theta} r. Hence r\rho_{\theta} P = \rho_{-\theta} r P = P. Multiply both sides by \rho_\theta to have rP = \rho_{\theta} P.

(1) Thus P has reflection symmetry iff rP = \rho_{\theta}P for some angle \theta.

This simple fact enables a easy method to determine if P has reflection symmetry. Take a simple polygon P. First assume the centroid of P is the origin this is needed to ensure that a rotation about the x-axis is a rotation of P and not a rotation and translation of P.

From (1) we know that rP = \rho_\theta P for some angle \theta. To determine \theta we pick a vertex, v, of P. We know that v is rotated into some vertex w of rP. Hence we try rotating v into every vertex w of rP until we get a match.

June 4, 2008

CGAL

I’ve been absent mostly due to lazyness (also I’ve been having lots of fun outdoors see http://picasaweb.google.com/Bryan.W.Bell). I’ve tried using CGAL. But everytime I end up quitting in disgust after looking at code like the following

template<class Kernel, class Container>
Polygon_2<Kernel, Container> rotate_polygon(const Polygon_2<Kernel, Container>& p, Direction_2<Kernel> dir){
CGAL::Aff_transformation_2<Kernel> t(ROTATION, dir, ERROR_FACTOR);
return CGAL::transform(t, p);
}

I hate working in an environment where half of your mental energy is spent parsing the syntax of the code. After years of working in good environments such as python and C#. The above code is no fun to look at.

For fun I’ve attached a figure of the typically problem when fitting polygons

February 25, 2008

CGAL

Hopefully you remember the post I made back in Oct. 2007 about Rigorous Geometry. It turns out the CGAL project has a whole page devoted to this subject see CGAL/Philosophy. I suggest you read their thoughts on the subject since they’ve devoted considerable time to the problem.

Their solution to simplify considerably is to compute with numbers of arbitrary precision. They do this using either the GNU Multiple Precision Library or their own internal code.

I’ve decided to try implementing my project to solve Tanagram puzzles using the CGAL library. The downside is that CGAL is written in C++.

Next Page »

Blog at WordPress.com.