77import java .util .regex .Pattern ;
88
99import eu .mihosoft .vrl .v3d .Edge ;
10+ import eu .mihosoft .vrl .v3d .Extrude ;
1011import eu .mihosoft .vrl .v3d .Plane ;
1112import eu .mihosoft .vrl .v3d .Vector3d ;
1213import eu .mihosoft .vrl .v3d .Vertex ;
1314
1415public class BezierPath {
1516
17+ private static final double MaximumInterpolationStep = 0.5 ;
18+
1619 static final Matcher matchPoint = Pattern .compile ("\\ s*(\\ d+)[^\\ d]+(\\ d+)\\ s*" ).matcher ("" );
1720
1821 BezierListProducer path ;
1922
2023 private ArrayList <Vector3d > plInternal = new ArrayList <Vector3d >();
21- double resolution = 0.075 ;
24+ private final int resolutionPoints ;
2225
2326 /** Creates a new instance of Animate */
24- public BezierPath () {
25- }
26-
27- /** Creates a new instance of Animate */
28- public BezierPath (String path ) {
29- parsePathString (path );
27+ public BezierPath (int resolution ) {
28+ this .resolutionPoints = resolution ;
3029 }
3130
3231 public void parsePathString (String d ) {
@@ -57,7 +56,7 @@ protected void parsePathList(String list) {
5756 } else {
5857 tokens .addFirst (curToken );
5958 }
60- double x , y ;
59+ double x , y ;
6160 switch (curCmd ) {
6261 case 'M' :
6362 x = nextFloat (tokens );
@@ -108,53 +107,37 @@ protected void parsePathList(String list) {
108107 break ;
109108 case 'Q' :
110109 path .curvetoQuadraticAbs (nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ));
111- for (double i = resolution ; i < 1 ; i += resolution ) {
112- addingPoint (i );
113- }
110+ expandPath ();
114111 break ;
115112 case 'q' :
116113 path .curvetoQuadraticAbs (nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ));
117- for (double i = resolution ; i < 1 ; i += resolution ) {
118- addingPoint (i );
119- }
114+ expandPath ();
120115 break ;
121116 case 'T' :
122117 path .curvetoQuadraticSmoothAbs (nextFloat (tokens ), nextFloat (tokens ));
123- for (double i = resolution ; i < 1 ; i += resolution ) {
124- addingPoint (i );
125- }
118+ expandPath ();
126119 break ;
127120 case 't' :
128121 path .curvetoQuadraticSmoothRel (nextFloat (tokens ), nextFloat (tokens ));
129- for (double i = resolution ; i < 1 ; i += resolution ) {
130- addingPoint (i );
131- }
122+ expandPath ();
132123 break ;
133124 case 'C' :
134125 path .curvetoCubicAbs (nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ),
135126 nextFloat (tokens ), nextFloat (tokens ));
136- for (double i = resolution ; i < 1 ; i += resolution ) {
137- addingPoint (i );
138- }
127+ expandPath ();
139128 break ;
140129 case 'c' :
141130 path .curvetoCubicRel (nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ),
142131 nextFloat (tokens ), nextFloat (tokens ));
143- for (double i = resolution ; i < 1 ; i += resolution ) {
144- addingPoint (i );
145- }
132+ expandPath ();
146133 break ;
147134 case 'S' :
148135 path .curvetoCubicSmoothAbs (nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ));
149- for (double i = resolution ; i < 1 ; i += resolution ) {
150- addingPoint (i );
151- }
136+ expandPath ();
152137 break ;
153138 case 's' :
154139 path .curvetoCubicSmoothRel (nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ), nextFloat (tokens ));
155- for (double i = resolution ; i < 1 ; i += resolution ) {
156- addingPoint (i );
157- }
140+ expandPath ();
158141 break ;
159142 case 'Z' :
160143 case 'z' :
@@ -170,30 +153,57 @@ protected void parsePathList(String list) {
170153 }
171154 }
172155
156+ private void expandPath () {
157+ double resolution = getResolution ();
158+ for (double i = 0 ; i < 1 ; i += resolution ) {
159+ addingPoint (i );
160+ }
161+ addingPoint (1 );
162+ }
163+
164+ private double getResolution () {
165+ Vector3d start = path .bezierSegs .get (path .bezierSegs .size () - 1 ).eval (0 );
166+ Vector3d end = path .bezierSegs .get (path .bezierSegs .size () - 1 ).eval (1 );
167+ double magnitude = start .minus (end ).magnitude ();
168+ if (magnitude < Plane .getEPSILON ())
169+ return 1 ;
170+ double dpoints = magnitude /0.75 ;
171+ if (dpoints < 1 )
172+ dpoints = 1 ;
173+ double increment = 1.0 / dpoints ;
174+ double min = 1.0 / ((double ) resolutionPoints );
175+ if (increment < min )
176+ increment = min ;
177+ if (increment > MaximumInterpolationStep )
178+ increment = MaximumInterpolationStep ;
179+ // System.out.println("Path with inc "+points);
180+ return increment ;
181+ }
182+
173183 private boolean addingPoint (double i ) {
174184 Vector3d eval = path .bezierSegs .get (path .bezierSegs .size () - 1 ).eval (i );
175185 return setThePoint (eval );
176186 }
177187
178188 private boolean setThePoint (Vector3d eval ) {
179- int end = plInternal .size ()-1 ;
180-
181- for (Vector3d v :plInternal ) {
182- if (Math .abs (v .minus (eval ).magnitude ())<0.001 ) {
183- return false ;
189+ int end = plInternal .size () - 1 ;
190+ for (int i = 0 ; i < plInternal .size (); i ++)
191+ if (end > 0 ) {
192+ if (Math .abs (plInternal .get (i ).minus (eval ).magnitude ()) < Extrude .getMinimumDIstance ()) {
193+ return false ;
194+ }
184195 }
185- }
186- if (plInternal .size ()>1 ) {
187- Edge e = new Edge (new Vertex (plInternal .get (end -1 ),null ), new Vertex (plInternal .get (end ),null ));
188- if (e .colinear (eval )) {
196+ if (plInternal .size () > 1 ) {
197+ Edge e = new Edge (new Vertex (plInternal .get (end - 1 )), new Vertex (plInternal .get (end )));
198+ if (e .colinear (eval )) {
189199 plInternal .set (end , eval );
190200 return true ;
191201 }
192202 }
193203 return plInternal .add (eval );
194204 }
195205
196- static protected double nextFloat (LinkedList <String > l ) {
206+ static protected double nextFloat (LinkedList <String > l ) {
197207 String s = l .removeFirst ();
198208 return Float .parseFloat (s );
199209 }
@@ -202,12 +212,12 @@ static protected double nextFloat(LinkedList<String> l) {
202212 * Evaluates this animation element for the passed interpolation time. Interp
203213 * must be on [0..1].
204214 */
205- public Vector3d eval (double interp ) {
215+ public Vector3d eval (double interp ) {
206216 Vector3d point = new Vector3d (0 , 0 );// = new Vector3d();
207- if (interp < 0.001 )
208- interp = (double ) 0.001 ;
209- if (interp > 0.9999 )
210- interp = (double ) 0.9999 ;
217+ // if (interp < 0.001)
218+ // interp = (double ) 0.001;
219+ // if (interp > 0.9999)
220+ // interp = (double ) 0.9999;
211221
212222 double curLength = path .curveLength * interp ;
213223 for (Iterator <Bezier > it = path .bezierSegs .iterator (); it .hasNext ();) {
0 commit comments