/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2013 - Scilab Enterprises - Calixte Denizet
+ * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
package org.scilab.forge.scirenderer.implementation.g2d.motor;
+import java.awt.*;
import java.awt.Color;
-import java.awt.Stroke;
-import java.awt.geom.Line2D;
-import java.awt.geom.Path2D;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
+import org.scilab.forge.scirenderer.implementation.g2d.*;
import org.scilab.forge.scirenderer.tranformations.Vector3d;
-import org.scilab.forge.scirenderer.tranformations.Vector4d;
/**
- * Class to represent a polyline object. This is used only in 2D (in 3D, a line could begin
- * on front of a face and could end behind it).
- * This allows to draw a polyline like a polyline ! and not as a set of segments.
- * Notice that a PolyLine is NOT a convex object... but in 2D it does not matter, algorithms
- * which use the convexity are not applyed.
- *
* @author Calixte DENIZET
*/
-public class PolyLine extends ConvexObject {
+public class PolyLine {
+ /* extends AbstractDrawable3DObject {
private boolean monochromatic;
- private G2DStroke stroke;
-
- /**
- * Default constructor
- * @param vertices the polyline vertices
- * @param colors the vertices color
- * @param stroke the stroke to used
- */
- public PolyLine(Vector3d[] vertices, Color[] colors, G2DStroke stroke) throws InvalidPolygonException {
- super(vertices, colors);
- if (vertices.length <= 1) {
- throw new InvalidPolygonException("A polyline cannot have one or zero point");
- }
-
- this.monochromatic = isMonochromatic(colors);
- this.stroke = stroke;
+ private Stroke stroke;
+ private Shape clip;
+
+ public PolyLine(Vector3d[] vertices, Color[] colors, Stroke stroke, Shape clip) throws InvalidPolygonException {
+ super(vertices, colors);
+ this.monochromatic = isMonochromatic(colors);
+ this.stroke = stroke;
+ this.clip = clip;
}
- /**
- * Get a set of polylines. The Nan of Inf vectors are removed and so the polyline is splitted.
- * @param vertices the polyline vertices
- * @param colors the vertices color
- * @param stroke the stroke to used
- * @param loop if true a looping polyline is created
- * @return a set of polylines
- */
- public static List<PolyLine> getPolyLines(Vector3d[] vertices, Color[] colors, G2DStroke stroke, boolean loop) {
- if (loop) {
- Vector3d[] v = new Vector3d[vertices.length + 1];
- Color[] c = new Color[vertices.length + 1];
- for (int i = 0; i < vertices.length; i++) {
- v[i] = vertices[i];
- c[i] = colors[i];
- }
- v[vertices.length] = v[0];
- c[vertices.length] = c[0];
- vertices = v;
- colors = c;
- }
-
- int pos = 0;
- List<PolyLine> list = new ArrayList<PolyLine>(1);
- while ((pos = trimLeft(vertices, pos)) != -1) {
- final int second = findNanOrInf(vertices, pos + 1);
- final int len = second - pos;
- final Vector3d[] newVertices = new Vector3d[len];
- final Color[] newColors = new Color[len];
- for (int i = 0; i < len; i++) {
- newVertices[i] = vertices[pos + i];
- newColors[i] = colors[pos + i];
- }
- pos = second + 1;
- try {
- list.add(new PolyLine(newVertices, newColors, stroke));
- } catch (InvalidPolygonException e) { }
- }
+ @Override
+ protected Path2D getProjectedPolyLine() {
+ int i;
+ Path2D.Double path = new Path2D.Double();
- return list;
+ // Trim on the left
+ for (i = 0; i < vertices.length; i++) {
+ if (!AbstractDrawable3DObject.isNanOrInf(vertices[i])) {
+ break;
}
-
- /**
- * {@inheritDoc}
- */
- public List<ConvexObject> breakObject(Vector4d v) {
- final double[] vv = v.getData();
- final Vector3d np = new Vector3d(vv);
- final List<ConvexObject> list = new ArrayList<ConvexObject>(1);
-
- int pos = 0;
- boolean prev = false;
-
- for (int i = 0; i < vertices.length; i++) {
- final boolean b = isBehind(vertices[i], np, vv[3]);
- if (b && !prev) {
- pos = i;
- prev = true;
- } else if (!b && prev) {
- prev = false;
- try {
- list.add(cut(pos, i, np, vv[3]));
- } catch (InvalidPolygonException e) { }
- }
- }
-
- if (prev) {
- try {
- list.add(cut(pos, vertices.length, np, vv[3]));
- } catch (InvalidPolygonException e) { }
- }
-
- return list;
}
- /**
- * {@inheritDoc}
- */
- public List<ConvexObject> breakObject(ConvexObject o) {
- return null;
+ if (i < vertices.length) {
+ path.moveTo(vertices[i].getX(), vertices[i].getY());
+ i++;
+ boolean broken = false;
+ for (; i < vertices.length; i++) {
+ if (AbstractDrawable3DObject.isNanOrInf(vertices[i])) {
+ if (!broken) {
+ broken = true;
}
-
- /**
- * {@inheritDoc}
- */
- protected boolean isDegenerate() {
- return false;
+ } else {
+ if (broken) {
+ broken = false;
+ path.moveTo(vertices[i].getX(), vertices[i].getY());
+ } else {
+ path.lineTo(vertices[i].getX(), vertices[i].getY());
}
-
- /**
- * {@inheritDoc}
- */
- protected boolean isNanOrInf() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public Vector3d getNormal() {
- // Never used
- return null;
}
-
- /**
- * {@inheritDoc}
- */
- protected boolean isPlanar() {
- // Never used
- return true;
}
-
- /**
- * Cut a polyline on a clipping plane
- * @param first the first vertex position
- * @param second the second vertex position
- * @param np the normal vector of the clipping plane
- * @param C the constant part of the hyperplane
- * @return a cutted PolyLine
- */
- private PolyLine cut(int first, int second, Vector3d np, double C) throws InvalidPolygonException {
- final boolean cutAtBegin = first != 0;
- final boolean cutAtEnd = second != vertices.length;
-
- if (!cutAtBegin && !cutAtEnd) {
- return this;
- }
-
- if (cutAtBegin && cutAtEnd) {
- final int len = second - first + 2;
-
- Vector3d[] newVertices = new Vector3d[len];
- Color[] newColors = new Color[len];
-
- for (int i = 1; i < len - 1; i++) {
- newVertices[i] = vertices[first + i - 1];
- newColors[i] = colors[first + i - 1];
- }
-
- double c = (C + vertices[first].scalar(np)) / vertices[first].minus(vertices[first - 1]).scalar(np);
- newVertices[0] = Vector3d.getBarycenter(vertices[first - 1], vertices[first], c, 1 - c);
- newColors[0] = getColorsBarycenter(colors[first - 1], colors[first], c, 1 - c);
-
- c = (C + vertices[second].scalar(np)) / vertices[second].minus(vertices[second - 1]).scalar(np);
- newVertices[len - 1] = Vector3d.getBarycenter(vertices[second - 1], vertices[second], c, 1 - c);
- newColors[len - 1] = getColorsBarycenter(colors[second - 1], colors[second], c, 1 - c);
-
- return new PolyLine(newVertices, newColors, this.stroke);
- }
-
- if (cutAtBegin) {
- final double c = (C + vertices[first].scalar(np)) / vertices[first].minus(vertices[first - 1]).scalar(np);
- final int len = second - first + 1;
-
- Vector3d[] newVertices = new Vector3d[len];
- Color[] newColors = new Color[len];
-
- for (int i = 1; i < len; i++) {
- newVertices[i] = vertices[first + i - 1];
- newColors[i] = colors[first + i - 1];
- }
-
- newVertices[0] = Vector3d.getBarycenter(vertices[first - 1], vertices[first], c, 1 - c);
- newColors[0] = getColorsBarycenter(colors[first - 1], colors[first], c, 1 - c);
-
- return new PolyLine(newVertices, newColors, this.stroke);
- } else {
- final double c = (C + vertices[second].scalar(np)) / vertices[second].minus(vertices[second - 1]).scalar(np);
- final int len = second - first + 1;
-
- Vector3d[] newVertices = new Vector3d[len];
- Color[] newColors = new Color[len];
-
- for (int i = 0; i < len - 1; i++) {
- newVertices[i] = vertices[first + i];
- newColors[i] = colors[first + i];
- }
-
- newVertices[len - 1] = Vector3d.getBarycenter(vertices[second - 1], vertices[second], c, 1 - c);
- newColors[len - 1] = getColorsBarycenter(colors[second - 1], colors[second], c, 1 - c);
- return new PolyLine(newVertices, newColors, this.stroke);
- }
}
-
- @Override
- protected Path2D getProjectedPolyLine() {
- Path2D.Double path = new Path2D.Double();
-
- path.moveTo(vertices[0].getX(), vertices[0].getY());
- for (int i = 1; i < vertices.length; i++) {
- path.lineTo(vertices[i].getX(), vertices[i].getY());
- }
-
- return path;
+ return path;
}
- @Override
public void draw(Graphics2D g2d) {
- Stroke oldStroke = g2d.getStroke();
-
- if (monochromatic) {
- g2d.setColor(colors[0]);
- g2d.setStroke(stroke);
- g2d.draw(getProjectedPolyLine());
- } else {
- // on peut surement faire mieux ici
- // avec un LinearGradientPaint
- Vector3d start = vertices[0];
- Color color = colors[0];
- double cumLen = 0;
- float[] dashArray = stroke.getDashArray();
- float lwidth = stroke.getLineWidth();
- for (int i = 1; i < vertices.length; i++) {
- Stroke nstroke = new G2DStroke(lwidth, dashArray, (float) cumLen);
- g2d.setStroke(nstroke);
- g2d.setColor(color);
- g2d.draw(new Line2D.Double(start.getX(), start.getY(), vertices[i].getX(), vertices[i].getY()));
- cumLen += Math.hypot(start.getX() - vertices[i].getX(), start.getY() - vertices[i].getY());
- }
- }
-
- g2d.setStroke(oldStroke);
+ Shape oldClip = g2d.getClip();
+ Stroke oldStroke = g2d.getStroke();
+
+ g2d.clip(clip);
+
+ if (monochromatic) {
+ g2d.setColor(colors[0]);
+ g2d.setStroke(stroke);
+ g2d.draw(getProjectedPolyLine());
+ } else {
+ Vector3D start = null;
+ Color color = null;
+ double cumLen = 0;
+ float[] dashArray = stroke.getDashArray();
+ float lwidth = stroke.getLineWidth();
+ for (int i = 0; i < vertices.length; i++) {
+ if (AbstractDrawable3DObject.isNanOrInf(vertices[i])) {
+ start = null;
+ } else {
+ if (start == null) {
+ start = vertices[i];
+ color = colors[i];
+ } else {
+ Stroke nstroke = new G2DStroke(lwidth, dashArray, cumLen);
+ g2d.setStroke(nstroke);
+ g2d.setColor(color);
+ g2d.draw(new Line2D.Double(start.getX(), start.getY(), vertices[i].getX(), vertices[i].getY()));
+ cumLen += Math.hypot(start.getX() - vertices[i].getX(), start.getY() - vertices[i].getY());
}
-
- /**
- * Get first non Nan (or Inf) vector position
- * @param v the array to trim
- * @param start the starting position
- * @return index of the first non Nan vector or -1 if not found
- */
- private static int trimLeft(Vector3d[] v, int start) {
- for (int i = start; i < v.length; i++) {
- if (!isNanOrInf(v[i])) {
- return i;
- }
- }
-
- return -1;
}
-
- /**
- * Get first Nan (or Inf) vector position
- * @param v the array to trim
- * @param start the starting position
- * @return index of the first Nan vector
- */
- private static int findNanOrInf(Vector3d[] v, int start) {
- for (int i = start; i < v.length; i++) {
- if (isNanOrInf(v[i])) {
- return i;
- }
- }
-
- return v.length;
}
+ }
+
+ g2d.setClip(oldClip);
+ g2d.setStroke(oldStroke);
+ }*/
}