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 / Segment.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  */
11
12 package org.scilab.forge.scirenderer.implementation.g2d.motor;
13
14 import java.awt.Color;
15 import java.awt.Graphics2D;
16 import java.awt.Stroke;
17 import java.awt.geom.Path2D;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.List;
21 import java.util.HashSet;
22 import java.util.Set;
23
24 import org.scilab.forge.scirenderer.tranformations.Vector3d;
25 import org.scilab.forge.scirenderer.tranformations.Vector4d;
26
27 /**
28  * @author Calixte DENIZET
29  */
30 public class Segment extends ConvexObject implements Comparable<Segment> {
31
32     private Integer hash;
33     protected Stroke stroke;
34     protected List<ConvexObject> segmentOn;
35
36     public Segment(Vector3d[] vertices, Color[] colors, Stroke stroke) throws InvalidPolygonException {
37         super(vertices, colors);
38         if (vertices.length != 2) {
39             throw new InvalidPolygonException("Invalid segment: must have 2 vertices.");
40         }
41         this.stroke = stroke;
42     }
43
44     public Segment(Vector3d[] vertices, Color[] colors) throws InvalidPolygonException {
45         this(vertices, colors, null);
46     }
47
48     public void setStroke(Stroke stroke) {
49         this.stroke = stroke;
50     }
51
52     public double getLength() {
53         return vertices[0].minus(vertices[1]).getNorm();
54     }
55
56     public static double getLength(Vector3d[] vertices) {
57         return vertices[0].minus(vertices[1]).getNorm();
58     }
59
60     public void addConvexObject(ConvexObject co) {
61         if (segmentOn == null) {
62             segmentOn = new ArrayList<ConvexObject>(2);
63         }
64         segmentOn.add(co);
65     }
66
67     public void removeConvexObject(ConvexObject co) {
68         if (segmentOn != null) {
69             segmentOn.remove(co);
70         }
71     }
72
73     public void replaceSegment(List<Segment> segs) {
74         if (segmentOn != null) {
75             for (ConvexObject co : segmentOn) {
76                 Triangle t = (Triangle) co;
77                 t.replaceSegment(this, segs);
78             }
79         }
80     }
81
82     public boolean isIn2D() {
83         return isNull(vertices[0].getZ()) && isNull(vertices[1].getZ());
84     }
85
86     public boolean isInFront() {
87         return isEqual(vertices[0].getZ(), -0.5) && isEqual(vertices[1].getZ(), -0.5);
88     }
89
90     @Override
91     public int compareTo(Segment o) {
92         if (equals(o)) {
93             return 0;
94         }
95
96         return getPrecedence() - o.getPrecedence();
97     }
98
99     @Override
100     public boolean equals(Object o) {
101         if (o instanceof Segment) {
102             Segment s = (Segment) o;
103             return (s.vertices[0].equals(vertices[0]) && s.vertices[1].equals(vertices[1]) && s.colors[0].equals(colors[0]) && s.colors[1].equals(colors[1])) || (s.vertices[1].equals(vertices[0]) && s.vertices[0].equals(vertices[1]) && s.colors[1].equals(colors[0]) && s.colors[0].equals(colors[1]));
104         }
105
106         return false;
107     }
108
109     @Override
110     public int isBehind(ConvexObject o) {
111         if (o instanceof Triangle && ((Triangle) o).isSegmentAcross(this)) {
112             return 1;
113         }
114
115         return super.isBehind(o);
116     }
117
118     @Override
119     public List<ConvexObject> breakObject(ConvexObject o) {
120         if (o instanceof Triangle) {
121             return ((Triangle) o).breakObject(this);
122         } else if (o instanceof SpritedRectangle) {
123             return ((SpritedRectangle) o).breakObject(this);
124         }
125
126         return null;
127     }
128
129     @Override
130     public List<ConvexObject> breakObject(Vector4d v) {
131         double[] vv = v.getData();
132         Vector3d np = new Vector3d(vv);
133         boolean a = isBehind(vertices[0], np, vv[3]);
134         boolean b = isBehind(vertices[1], np, vv[3]);
135
136         if (a && b) {
137             List<ConvexObject> list = new ArrayList<ConvexObject>(1);
138             list.add(this);
139             return list;
140         }
141
142         if (!a && !b) {
143             return null;
144         }
145
146         double c = (vv[3] + vertices[1].scalar(np)) / v0.scalar(np);
147         Vector3d p = Vector3d.getBarycenter(vertices[0], vertices[1], c, 1 - c);
148         Color color = getColorsBarycenter(colors[0], colors[1], c, 1 - c);
149         Vector3d[] vs = null;
150         Color[] cs = null;
151
152         if (a) {
153             vs = new Vector3d[] {vertices[0], p};
154             cs = new Color[] {colors[0], color};
155         }
156
157         if (b) {
158             vs = new Vector3d[] {p, vertices[1]};
159             cs = new Color[] {color, colors[1]};
160         }
161
162         try {
163             List<ConvexObject> list = new ArrayList<ConvexObject>(1);
164             list.add(new Segment(vs, cs, this.stroke));
165
166             return list;
167         } catch (InvalidPolygonException e) { }
168
169         return null;
170     }
171
172     public List<Segment> breakObject(Vector3d p, Vector3d u, Vector3d n) {
173         double c = vertices[1].minus(p).scalar(n) / v0.scalar(n);
174         if (c > 0 && !isNull(c) && c < 1 && !isEqual(c, 1)) {
175             List<Segment> list = new ArrayList<Segment>(2);
176             Vector3d q = Vector3d.getBarycenter(vertices[0], vertices[1], c, 1 - c);
177             Color color = getColorsBarycenter(colors[0], colors[1], c, 1 - c);
178             try {
179                 list.add(new Segment(new Vector3d[] {vertices[0], q}, new Color[] {colors[0], color}, stroke));
180                 list.add(new Segment(new Vector3d[] {q, vertices[1]}, new Color[] {color, colors[1]}, stroke));
181
182                 return list;
183             } catch (InvalidPolygonException e) { }
184         } else {
185             List<Segment> list = new ArrayList<Segment>(1);
186             try {
187                 list.add(new Segment(new Vector3d[] {vertices[0], vertices[1]}, new Color[] {colors[0], colors[1]}, stroke));
188
189                 return list;
190             } catch (InvalidPolygonException e) { }
191         }
192
193         return null;
194     }
195
196     @Override
197     public void draw(Graphics2D g2d) {
198         if (segmentOn == null || segmentOn.isEmpty()) {
199             Path2D polyline = getProjectedPolyLine();
200             g2d.setColor(colors[0]);
201             Stroke oldStroke = g2d.getStroke();
202             if (oldStroke != stroke) {
203                 g2d.setStroke(stroke);
204             }
205
206             g2d.draw(polyline);
207
208             if (oldStroke != stroke) {
209                 g2d.setStroke(oldStroke);
210             }
211
212             drawAreas(g2d);
213         }
214     }
215
216     @Override
217     public int hashCode() {
218         if (hash == null) {
219             hash = Arrays.hashCode(vertices) + 19 * Arrays.hashCode(colors);
220         }
221         return hash;
222     }
223
224     @Override
225     public String toString() {
226         return "Segment " + vertices[0].toString() + " " + vertices[1].toString() + " Precedence: " + getPrecedence();
227     }
228 }