/* GeoGebra - Dynamic Mathematics for Everyone http://www.geogebra.org This file is part of GeoGebra. This program 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. */ /* * AlgoVertex.java * * Created on 11. November 2001, 21:37 */ package org.geogebra.common.kernel.algos; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoNumberValue; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.geos.GeoPoly; import org.geogebra.common.kernel.kernelND.GeoPointND; /** * * @author Zbynek */ public class AlgoVertexPolygon extends AlgoElement { protected GeoPoly p; // input private GeoNumberValue index; private GeoPointND oneVertex; private OutputHandler<GeoElement> outputPoints; /** * Creates new vertex algo * * @param cons * construction * @param labels * labels for vertices * @param p * polygon or polyline */ public AlgoVertexPolygon(Construction cons, String[] labels, GeoPoly p) { this(cons, p); // if only one label (e.g. "A"), new labels will be A_1, A_2, ... setLabels(labels); update(); // set labels dependencies: will be used with // Construction.resolveLabelDependency() } private void setLabels(String[] labels) { // if only one label (e.g. "A") for more than one output, new labels // will be A_1, A_2, ... if (labels != null && labels.length == 1 && // outputPoints.size() > 1 && labels[0] != null && !labels[0].equals("")) { outputPoints.setIndexLabels(labels[0]); } else { outputPoints.setLabels(labels); outputPoints.setIndexLabels(outputPoints.getElement(0) .getLabel(StringTemplate.defaultTemplate)); } } /** * @param cons * construction * @param label * label * @param p * polygon or polyline * @param v * vertex index */ public AlgoVertexPolygon(Construction cons, String label, GeoPoly p, GeoNumberValue v) { this(cons, p, v); oneVertex.setLabel(label); } /** * Creates algo for Vertex[poly] (many output points) Creates new unlabeled * vertex algo * * @param cons * construction * @param p * polygon or polyline */ protected AlgoVertexPolygon(Construction cons, GeoPoly p) { super(cons); this.p = p; outputPoints = createOutputPoints(); outputPoints.adjustOutputSize(1); setInputOutput(); // for AlgoElement compute(); } /** * Creates algo for Vertex[poly,n] (one output) * * @param cons * construction or polyline * @param p * polygon or polyline * @param v * vertrex index */ AlgoVertexPolygon(Construction cons, GeoPoly p, GeoNumberValue v) { super(cons); this.p = p; this.index = v; oneVertex = newGeoPoint(cons); setInputOutput(); // for AlgoElement compute(); } /** * @param cons * @return new GeoPointND */ public GeoPointND newGeoPoint(Construction cons) { return new GeoPoint(cons); } @Override public Commands getClassName() { return Commands.Vertex; } // for AlgoElement @Override public void setInputOutput() { if (index != null) { input = new GeoElement[2]; input[1] = index.toGeoElement(); setOutputLength(1); setOutput(0, (GeoElement) oneVertex); } else { input = new GeoElement[1]; } input[0] = (GeoElement) p; setDependencies(); // done by AlgoElement } /** * Returns the polygon * * @return input polygon */ public GeoPoly getPolygon() { return p; } @Override public int getOutputLength() { if (index != null) { return 1; } return outputPoints.size(); } @Override public final void compute() { if (index != null) { if (!p.isDefined()) { oneVertex.setUndefined(); } else { int i = (int) Math.floor(index.getDouble()) - 1; if (i >= p.getPoints().length || i < 0) { oneVertex.setUndefined(); } else { setPoint(oneVertex, i); } } oneVertex.update(); return; } if (!p.isDefined()) { for (int i = 0; i < outputPoints.size(); i++) { outputPoints.getElement(i).setUndefined(); } return; } int length = p.getPoints().length; // Log.debug(length); if (length > outputPoints.size()) { outputPoints.adjustOutputSize(length); refreshOutput(); } for (int i = 0; i < length; i++) { GeoPointND point = (GeoPointND) outputPoints.getElement(i); setPoint(point, i); } // other points are undefined for (int i = length; i < outputPoints.size(); i++) { outputPoints.getElement(i).setUndefined(); } } /** * set the point to the i-th of the polygon * * @param point * @param i */ protected void setPoint(GeoPointND point, int i) { point.set(p.getPointND(i)); } @Override public final String toString(StringTemplate tpl) { return getLoc().getPlain("VertexOfA", ((GeoElement) p).getLabel(tpl)); } /** * Returns list of the vertices * * @return list of the vertices */ public GeoElement[] getVertex() { return getOutput(); } @Override public GeoElement getOutput(int i) { if (index != null) { return (GeoElement) oneVertex; } return outputPoints.getElement(i); } /** * @return the vertex when called as Vertex[poly,number] */ public GeoPointND getOneVertex() { return oneVertex; } protected OutputHandler<GeoElement> createOutputPoints() { return new OutputHandler<GeoElement>(new elementFactory<GeoElement>() { @Override public GeoPoint newElement() { GeoPoint pt = new GeoPoint(cons); pt.setCoords(0, 0, 1); pt.setParentAlgorithm(AlgoVertexPolygon.this); return pt; } }); } }