Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Area intersection does not work as expected #21

Open
paulis opened this issue Mar 6, 2013 · 1 comment
Open

Area intersection does not work as expected #21

paulis opened this issue Mar 6, 2013 · 1 comment

Comments

@paulis
Copy link

paulis commented Mar 6, 2013

I have a test with two hexagonal shapes and a rectangle intersecting both of those hexagons. I intersect the hexagons separately expecting to have two different intersection areas but I end up with two identical intersection areas.

@paulis
Copy link
Author

paulis commented Mar 6, 2013

intersectJavaAreas works but intersectPyhtagorasAreas does not

import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

import pythagoras.f.Area;
import pythagoras.f.Path;
import pythagoras.f.PathIterator;
import pythagoras.f.Point;

/**
 * <pre>
 *  NW _____NE
 *    /hex1 \
 * W /   _   \ E
 *   \  | |  /
 *    \_|_|_/
 *    / | | \
 *   /  |_|  \
 *   \       /
 *    \hex2_/
 *   SW     SE
 * </pre>
 * 
 * 
 */
public class AreaIntersectionTest {
    private final float[] hex1Points = new float[]{240.0f, 238.0f, 260.0f, 272.0f, 240.0f, 306.0f, 200.0f, 306.0f, 180.0f, 272.0f, 200.0f, 238.0f};
    private final float[] hex2Points = new float[]{240.0f, 306.0f, 260.0f, 340.0f, 240.0f, 374.0f, 200.0f, 374.0f, 180.0f, 340.0f, 200.0f, 306.0f};
    private final float[] rectPoints = new float[]{220.0f, 260.0f, 230.0f, 260.0f, 230.0f, 350.0f, 220.0f, 350.0f};

    @Test
    public void intersectJavaAreas() {

        java.awt.geom.Area javaHex1 = toJavaArea(hex1Points);
        java.awt.geom.Area javaHex2 = toJavaArea(hex2Points);
        java.awt.geom.Area javaRect = toJavaArea(rectPoints);

        javaHex1.intersect(javaRect);
        javaHex2.intersect(javaRect);

        // This is as it should be.
        Assert.assertFalse(javaHex1.equals(javaHex2));

        List<Point> corners1 = corners(javaHex1);
        List<Point> corners2 = corners(javaHex2);
        assertRect(corners1, corners2);
    }

    @Test
    public void intersectPyhtagorasAreas() {

        Area hex1 = toArea(hex1Points);
        Area hex2 = toArea(hex2Points);
        Area rectangle = toArea(rectPoints);

        // Intersect both hexes with the rectangle
        hex1.intersect(rectangle);
        hex2.intersect(rectangle);

        // This asserts just fine
        Assert.assertFalse(hex1.equals(hex2));

        List<Point> corners1 = corners(hex1);
        List<Point> corners2 = corners(hex2);
        assertRect(corners1, corners2);

    }

    private void assertRect(List<Point> corners1, List<Point> corners2) {
        Assert.assertEquals(4, corners1.size());
        Assert.assertEquals(4, corners2.size());

        Point p1 = corners1.get(0);
        Point p2 = corners1.get(1);
        Point p3 = corners1.get(2);
        Point p4 = corners1.get(3);

        // All of these should not assert true
        // Assert.assertTrue(p1.equals(corners2.get(0)));
        // Assert.assertTrue(p2.equals(corners2.get(1)));
        // Assert.assertTrue(p3.equals(corners2.get(2)));
        // Assert.assertTrue(p4.equals(corners2.get(3)));

        boolean b1 = corners2.contains(p1);
        boolean b2 = corners2.contains(p2);
        boolean b3 = corners2.contains(p3);
        boolean b4 = corners2.contains(p4);

        // All points in intersection 1 cannot be in the intersection2
        Assert.assertFalse(b1 && b2 && b3 && b4);
    }


    private List<Point> corners(java.awt.geom.Area rect) {
        List<Point> points = new ArrayList<Point>();
        java.awt.geom.PathIterator iter = rect.getPathIterator(null);
        int segment = 0;
        Point p = null;
        do {
            float coords[] = new float[6];
            segment = iter.currentSegment(coords);
            switch (segment) {
                case PathIterator.SEG_CLOSE: 
                    break;
                case PathIterator.SEG_MOVETO: 
                    p = new Point(coords[0], coords[1]);
                    points.add(p);
                    break;
                case PathIterator.SEG_LINETO: 
                    p = new Point(coords[0], coords[1]);
                    points.add(p);
                    break;
                default:break;
            }

            iter.next();
        } while (!iter.isDone());
        return points;
    }

    private List<Point> corners(Area rect) {
        List<Point> points = new ArrayList<Point>();
        PathIterator iter = rect.pathIterator(null);
        int segment = 0;
        Point p = null;
        do {
            float coords[] = new float[6];
            segment = iter.currentSegment(coords);
            switch (segment) {
                case PathIterator.SEG_CLOSE: 
                    break;
                case PathIterator.SEG_MOVETO: 
                    p = new Point(coords[0], coords[1]);
                    points.add(p);
                    break;
                case PathIterator.SEG_LINETO: 
                    p = new Point(coords[0], coords[1]);
                    points.add(p);
                    break;
                default:break;
            }

            iter.next();
        } while (!iter.isDone());
        return points;
    }


    private Area toArea(float[] coords) {
        Path path = new Path();
        path.moveTo(coords[0], coords[1]); // NE
        for (int i = 2; i < coords.length; i++) {
            path.lineTo(coords[i], coords[++i]);
        }
        path.closePath();
        Area area = new Area(path);
        return area;

    }
    private java.awt.geom.Area toJavaArea(float[] coords) {
        Path2D javaPath = new Path2D.Float();
        javaPath.moveTo(coords[0], coords[1]); // NE
        for (int i = 2; i < coords.length; i++) {
            javaPath.lineTo(coords[i], coords[++i]);
        }
        javaPath.closePath();
        java.awt.geom.Area javaArea = new java.awt.geom.Area(javaPath);
        return javaArea;
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant