Revert "Bug 12212 fixed: Export a polyline in 2D broke it into several segments"
[scilab.git] / scilab / modules / scirenderer / src / org / scilab / forge / scirenderer / implementation / g2d / motor / PolyLine.java
index f3016b0..705a484 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * 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);
+    }*/
 }