/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package plugins.kernel.roi.roi2d; import icy.painter.Anchor2D; import icy.painter.LineAnchor2D; import icy.resource.ResourceUtil; import icy.type.geom.Polygon2D; import icy.type.point.Point5D; import icy.util.XMLUtil; import java.awt.Color; import java.awt.Polygon; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * ROI 2D polygon class. * * @author Stephane */ public class ROI2DPolygon extends ROI2DShape { protected class ROI2DPolygonAnchor2D extends LineAnchor2D { public ROI2DPolygonAnchor2D(Point2D position, Color color, Color selectedColor) { super(position, color, selectedColor); } @Override protected Anchor2D getPreviousPoint() { final int ind = controlPoints.indexOf(this); if (ind == 0) { if (controlPoints.size() > 1) return controlPoints.get(1); return null; } if (ind != -1) return controlPoints.get(ind - 1); return null; } } public static final String ID_POINTS = "points"; public static final String ID_POINT = "point"; /** * @deprecated */ @Deprecated public ROI2DPolygon(Point2D pt, boolean cm) { this(pt); } public ROI2DPolygon(Point2D pt) { super(new Polygon2D()); final Anchor2D point = createAnchor(pt); point.setSelected(true); addPoint(point); // set icon (default name is defined by getDefaultName()) setIcon(ResourceUtil.ICON_ROI_POLYGON); } /** * Generic constructor for interactive mode */ public ROI2DPolygon(Point5D pt) { this(pt.toPoint2D()); // getOverlay().setMousePos(pt); } public ROI2DPolygon(List<Point2D> points) { this(new Point2D.Double()); setPoints(points); unselectAllPoints(); } /** * @deprecated Better to use {@link #ROI2DPolygon(Polygon2D)} instead to have double point precision */ @Deprecated public ROI2DPolygon(Polygon polygon) { this(new Point2D.Double()); setPolygon(polygon); unselectAllPoints(); } public ROI2DPolygon(Polygon2D polygon) { this(new Point2D.Double()); setPolygon2D(polygon); unselectAllPoints(); } public ROI2DPolygon() { this(new Point2D.Double()); } @Override public String getDefaultName() { return "Polygon2D"; } @Override protected Anchor2D createAnchor(Point2D pos) { return new ROI2DPolygonAnchor2D(pos, getColor(), getFocusedColor()); } /** * @deprecated Use {@link #getPolygon2D()} instead */ @Deprecated protected Path2D getPath() { return new Path2D.Double(shape); } public void setPoints(List<Point2D> pts) { beginUpdate(); try { removeAllPoint(); for (Point2D pt : pts) addNewPoint(pt, false); } finally { endUpdate(); } } /** * @deprecated Use {@link #setPoints(List)} instead. */ @Deprecated public void setPoints(ArrayList<Point2D> pts) { setPoints((List<Point2D>) pts); } public Polygon2D getPolygon2D() { return (Polygon2D) shape; } public void setPolygon2D(Polygon2D polygon2D) { beginUpdate(); try { removeAllPoint(); for (int i = 0; i < polygon2D.npoints; i++) addNewPoint(new Point2D.Double(polygon2D.xpoints[i], polygon2D.ypoints[i]), false); } finally { endUpdate(); } } public Polygon getPolygon() { return getPolygon2D().getPolygon(); } public void setPolygon(Polygon polygon) { beginUpdate(); try { removeAllPoint(); for (int i = 0; i < polygon.npoints; i++) addNewPoint(new Point2D.Double(polygon.xpoints[i], polygon.ypoints[i]), false); } finally { endUpdate(); } } @Override protected void updateShape() { final int len; final double[] ptsX; final double[] ptsY; synchronized (controlPoints) { len = controlPoints.size(); ptsX = new double[len]; ptsY = new double[len]; for (int i = 0; i < len; i++) { final Anchor2D pt = controlPoints.get(i); ptsX[i] = pt.getX(); ptsY[i] = pt.getY(); } } final Polygon2D polygon2d = getPolygon2D(); // we can have a problem here if we try to redraw while we are modifying the polygon points synchronized (polygon2d) { polygon2d.npoints = len; polygon2d.xpoints = ptsX; polygon2d.ypoints = ptsY; polygon2d.calculatePath(); } // call super method after shape has been updated super.updateShape(); } @Override public boolean loadFromXML(Node node) { beginUpdate(); try { if (!super.loadFromXML(node)) return false; removeAllPoint(); final List<Node> nodesPoint = XMLUtil.getChildren(XMLUtil.getElement(node, ID_POINTS), ID_POINT); if (nodesPoint != null) { for (Node n : nodesPoint) { final Anchor2D pt = createAnchor(new Point2D.Double()); pt.loadPositionFromXML(n); addPoint(pt); } } } finally { endUpdate(); } return true; } @Override public boolean saveToXML(Node node) { if (!super.saveToXML(node)) return false; final Element nodePoints = XMLUtil.setElement(node, ID_POINTS); synchronized (controlPoints) { for (Anchor2D pt : controlPoints) pt.savePositionToXML(XMLUtil.addElement(nodePoints, ID_POINT)); } return true; } }