3

I've created a class that extends the awt.Polygon class. I'm trying to write a method that given the PathIterator of the polygon and a Point representing a vertex, adds the point at the appropriate location in the path.

For Example: A Polygon thats points are (0,0) (0,10) (10,10) (10,0) (A square), given the point (1,5) would make the polygon (0,0) (1,5) (0,10) (10,10) (10,0)

Thanks in advance

Valchris
  • 1,451
  • 2
  • 14
  • 33

2 Answers2

3

Expanding on @normalocity's idea, this appears to be a possible approach.

Addendum: For reference, this approach uses only public APIs, but other variations are possible.

Console:

MoveTo: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
LineTo: [0.0, 10.0, 0.0, 0.0, 0.0, 0.0]
LineTo: [10.0, 10.0, 0.0, 0.0, 0.0, 0.0]
LineTo: [10.0, 0.0, 0.0, 0.0, 0.0, 0.0]
Close:  [10.0, 0.0, 0.0, 0.0, 0.0, 0.0]

MoveTo: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
LineTo: [1.0, 5.0, 0.0, 0.0, 0.0, 0.0]
LineTo: [0.0, 10.0, 0.0, 0.0, 0.0, 0.0]
LineTo: [10.0, 10.0, 0.0, 0.0, 0.0, 0.0]
LineTo: [10.0, 0.0, 0.0, 0.0, 0.0, 0.0]
Close:  [10.0, 0.0, 0.0, 0.0, 0.0, 0.0]

Code:

import java.awt.Point;
import java.awt.Polygon;
import java.awt.geom.PathIterator;
import java.util.Arrays;

/** @see http://stackoverflow.com/questions/5877646 */
public class MyPoly extends Polygon {

    public static void main(String[] args) {
        final MyPoly square = new MyPoly();
        square.addPoint(0, 0);
        square.addPoint(0, 10);
        square.addPoint(10, 10);
        square.addPoint(10, 0);
        System.out.println(square.toString());
        MyPoly pentagon = square.insert(1, new Point(1, 5));
        System.out.println(pentagon.toString());
    }

    /**
     * Insert a point at the specified index
     *  
     * @param index at which to insert the new point
     * @param point the <code>Point</code> to insert
     * @return a new <code>Polygon</code> with the new <code>Point</code> 
     */
    public MyPoly insert(int index, Point point) {
        MyPoly mp = new MyPoly();
        PathIterator pi = this.getPathIterator(null);
        double[] coords = new double[6];
        int i = 0;
        while (!pi.isDone()) {
            if (i == index) {
                mp.addPoint(point.x, point.y);
            } else {
                if (pi.currentSegment(coords) != PathIterator.SEG_CLOSE) {
                    mp.addPoint((int) coords[0], (int) coords[1]);
                }
                pi.next();
            }
            i++;
        }
        return mp;
    }

    @Override
    public String toString() {
        PathIterator pi = this.getPathIterator(null);
        double[] coords = new double[6];
        StringBuilder sb = new StringBuilder();
        while (!pi.isDone()) {
            int kind = pi.currentSegment(coords);
            switch (kind) {
                case PathIterator.SEG_MOVETO:
                    sb.append("MoveTo: ");
                    break;
                case PathIterator.SEG_LINETO:
                    sb.append("LineTo: ");
                    break;
                case PathIterator.SEG_CLOSE:
                    sb.append("Close:  ");
                    break;
                default:
                    throw new IllegalArgumentException("Bad path segment");
            }
            sb.append(Arrays.toString(coords));
            sb.append("\n");
            pi.next();
        }
        return sb.toString();
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 1
    while this seems like it would work, it seems like an awful lot of work to just insert a point into two arrays. I'd just grab the xpoints and ypoints array, and recreate them with the new point added, using some simple System.arraycopy calls. – MeBigFatGuy May 04 '11 at 03:45
  • @MeBigFatGuy: Sounds like another answer to me! :-) I you pursue this avenue, I'd be curious if it can be done without recourse to the `PathIterator`. – trashgod May 04 '11 at 04:38
  • This assumes you know that the point should be inserted at 1. What if that is an unknown? it's supposed to alter the nearest line. Example a user wants to add a point above a square, at the midpoint x value. (Looking like a really basic house) – Valchris May 04 '11 at 04:42
  • The `index` is a parameter to `insert()`. – trashgod May 04 '11 at 04:47
1

Try using the "addPoint(x, y)" method, except write your own version (or override it) such that it lets you specify where the point is inserted in the series of points (e.g. first, second, third, etc.).

So, write a class that inherits from java.awt.Polygon public class InsertablePolygon extends java.awt.Polygon, and define a method on it, something like, public void insertPoint(int index, Point additionalPoint).

Inside the additionalPoint method, you should have direct access to the int[] xpoints and int[] ypoints arrays, which store the information. Simply modify those arrays (or copy them, insert your point, and then replace them), and you should be good.

jefflunt
  • 33,527
  • 7
  • 88
  • 126
  • That's what I'm asking help with. Few hours in and our solution has serious bugs. – Valchris May 04 '11 at 04:40
  • I've updated my answer. Also, see MeBigFatGuy's comment on trashgod's answer, which talks about the array copy operations, etc. – jefflunt May 04 '11 at 13:17
  • I think this a reasonable avenue to pursue, but I remain troubled by the need to update other internal state, such as `bounds` and `npoints`. I'm also uncertain how to account for the `PathIterator` segment types, except by using the public API. +1, btw. – trashgod May 04 '11 at 20:14