Revision 36

View differences:

org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/pom.xml
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2

  
3
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4
	<modelVersion>4.0.0</modelVersion>
5
	<artifactId>org.gvsig.jdk.v1_6</artifactId>
6
	<packaging>jar</packaging>
7
	<name>org.gvsig.jdk.v1_6</name>
8
	<description>Private classes of the OpenJDK v1.6</description>
9
	<parent>
10
		<groupId>org.gvsig</groupId>
11
		<artifactId>org.gvsig.jdk</artifactId>
12
		<version>1.0.2</version>
13
	</parent>
14
	<dependencies>
15
		<dependency>
16
			<groupId>org.gvsig</groupId>
17
			<artifactId>org.gvsig.tools.lib</artifactId>
18
		</dependency>
19
	</dependencies>
20

  
21
    <build>
22
        <plugins>
23
            <plugin>
24
                <groupId>org.apache.maven.plugins</groupId>
25
                <artifactId>maven-compiler-plugin</artifactId>
26
                <configuration>
27
                    <source>1.6</source>
28
                    <target>1.6</target>
29
                </configuration>
30
            </plugin>
31
        </plugins>
32
    </build>
33

  
34
</project>
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/javadoc/overview.html
1
<?xml version="1.0" encoding="UTF-8" ?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
<html xmlns="http://www.w3.org/1999/xhtml">
4
<head>
5
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
<title>${artifactId} package documentation</title>
7
</head>
8
<body>
9

  
10
	<p>TODO: Example library API overview.</p>
11
	
12
	<p>See the <a href="http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javadoc.html${symbol_pound}overviewcomment">Javadoc Tool documentation about the overview file</a></p>
13

  
14
</body>
15
</html>
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/java/org/gvsig/jdk/package.html
1
<?xml version="1.0" encoding="UTF-8" ?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
<html xmlns="http://www.w3.org/1999/xhtml">
4
<head>
5
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
<title>${package} package documentation</title>
7
</head>
8
<body>
9

  
10
	<p>TODO: Example library API description.</p>
11
	
12
	<p>See the <a href="http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javadoc.html${symbol_pound}packagecomment">Javadoc Tool documentation about the package file</a></p>
13

  
14
</body>
15
</html>
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/java/org/gvsig/jdk/GeomUtilities.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

  
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 {Iver T.I.}   {Task}
26
 */
27

  
28
package org.gvsig.jdk;
29

  
30
import java.awt.geom.PathIterator;
31

  
32
import org.gvsig.jdk.sun.awt.geom.Crossings;
33
import org.gvsig.jdk.sun.awt.geom.Curve;
34

  
35

  
36
/**
37
 * This class contains some utility methods to access to some 
38
 * private classes of the OpenJDK. These classes have been copied
39
 * to this package and their visibility has been reduced. It is not
40
 * possible to access them without using this class. 
41
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
42
 */
43
public class GeomUtilities {
44

  
45
	/**
46
	 * Tests if the specified rectangular area is inside the boundary of
47
	 * a <code>Shape</code>.
48
	 * @param pi the path iterator of a shape
49
	 * @param x,&nbsp;y the specified coordinates
50
	 * @param w the width of the specified rectangular area
51
	 * @param h the height of the specified rectangular area
52
	 * @return <code>true</code> if this <code>Shape</code> contains
53
	 * the specified rectangluar area; <code>false</code> otherwise.
54
	 */
55
	public static boolean contains(PathIterator pi, double x, double y, double w, double h) {
56
		Crossings c = Crossings.findCrossings(pi,
57
				x, y, x+w, y+h);
58
		return (c != null && c.covers(y, y+h));
59
	}
60
	
61
	/**
62
	 * Tests if the interior of a <code>Shape</code> intersects the
63
	 * interior of a specified set of rectangular coordinates.
64
	 * @param pi the path iterator of a shape
65
	 * @param x,&nbsp;y the specified coordinates
66
	 * @param w the width of the specified rectangular coordinates
67
	 * @param h the height of the specified rectangular coordinates
68
	 * @return <code>true</code> if this <code>Shape</code> and the
69
	 * interior of the specified set of rectangular coordinates intersect
70
	 * each other; <code>false</code> otherwise.
71
	 */
72
	public static boolean intersects(PathIterator pi, double x, double y, double w, double h) {
73
		Crossings c = Crossings.findCrossings(pi,
74
				x, y, x+w, y+h);
75
		return (c == null || !c.isEmpty());
76
	}
77
	
78
	 /**
79
     * Calculates the number of times the given path
80
     * crosses the ray extending to the right from (px,py).
81
     * If the point lies on a part of the path,
82
     * then no crossings are counted for that intersection.
83
     * +1 is added for each crossing where the Y coordinate is increasing
84
     * -1 is added for each crossing where the Y coordinate is decreasing
85
     * The path must start with a SEG_MOVETO, otherwise an exception is
86
     * thrown.
87
     * The caller must check p[xy] for NaN values.
88
     * The caller may also reject infinite p[xy] values as well.
89
     * @param pi the path iterator of a shape
90
     * @param px the x coordinate
91
     * @param py the y coordinate
92
     * @return is the sum of all crossings for every segment in
93
     * the path
94
     */
95
	public static int pointCrossingsForPath(PathIterator pi, double px, double py){
96
		return Curve.pointCrossingsForPath(pi, px, py);
97
	}
98

  
99
}
100

  
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/java/org/gvsig/jdk/sun/awt/geom/ChainEnd.java
1
/*
2
 * Copyright 1998 Sun Microsystems, Inc.  All Rights Reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Sun designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Sun in the LICENSE file that accompanied this code.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22
 * CA 95054 USA or visit www.sun.com if you need additional information or
23
 * have any questions.
24
 */
25

  
26
package org.gvsig.jdk.sun.awt.geom;
27

  
28
final class ChainEnd {
29
    CurveLink head;
30
    CurveLink tail;
31
    ChainEnd partner;
32
    int etag;
33

  
34
    ChainEnd(CurveLink first, ChainEnd partner) {
35
        this.head = first;
36
        this.tail = first;
37
        this.partner = partner;
38
        this.etag = first.getEdgeTag();
39
    }
40

  
41
    public CurveLink getChain() {
42
        return head;
43
    }
44

  
45
    public void setOtherEnd(ChainEnd partner) {
46
        this.partner = partner;
47
    }
48

  
49
    public ChainEnd getPartner() {
50
        return partner;
51
    }
52

  
53
    /*
54
     * Returns head of a complete chain to be added to subcurves
55
     * or null if the links did not complete such a chain.
56
     */
57
    public CurveLink linkTo(ChainEnd that) {
58
        if (etag == AreaOp.ETAG_IGNORE ||
59
            that.etag == AreaOp.ETAG_IGNORE)
60
        {
61
            throw new InternalError("ChainEnd linked more than once!");
62
        }
63
        if (etag == that.etag) {
64
            throw new InternalError("Linking chains of the same type!");
65
        }
66
        ChainEnd enter, exit;
67
        // assert(partner.etag != that.partner.etag);
68
        if (etag == AreaOp.ETAG_ENTER) {
69
            enter = this;
70
            exit = that;
71
        } else {
72
            enter = that;
73
            exit = this;
74
        }
75
        // Now make sure these ChainEnds are not linked to any others...
76
        etag = AreaOp.ETAG_IGNORE;
77
        that.etag = AreaOp.ETAG_IGNORE;
78
        // Now link everything up...
79
        enter.tail.setNext(exit.head);
80
        enter.tail = exit.tail;
81
        if (partner == that) {
82
            // Curve has closed on itself...
83
            return enter.head;
84
        }
85
        // Link this chain into one end of the chain formed by the partners
86
        ChainEnd otherenter = exit.partner;
87
        ChainEnd otherexit = enter.partner;
88
        otherenter.partner = otherexit;
89
        otherexit.partner = otherenter;
90
        if (enter.head.getYTop() < otherenter.head.getYTop()) {
91
            enter.tail.setNext(otherenter.head);
92
            otherenter.head = enter.head;
93
        } else {
94
            otherexit.tail.setNext(enter.head);
95
            otherexit.tail = enter.tail;
96
        }
97
        return null;
98
    }
99

  
100
    public void addLink(CurveLink newlink) {
101
        if (etag == AreaOp.ETAG_ENTER) {
102
            tail.setNext(newlink);
103
            tail = newlink;
104
        } else {
105
            newlink.setNext(head);
106
            head = newlink;
107
        }
108
    }
109

  
110
    public double getX() {
111
        if (etag == AreaOp.ETAG_ENTER) {
112
            return tail.getXBot();
113
        } else {
114
            return head.getXBot();
115
        }
116
    }
117
}
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/java/org/gvsig/jdk/sun/awt/geom/Crossings.java
1
/*
2
 * Copyright 1998-2003 Sun Microsystems, Inc.  All Rights Reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Sun designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Sun in the LICENSE file that accompanied this code.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22
 * CA 95054 USA or visit www.sun.com if you need additional information or
23
 * have any questions.
24
 */
25

  
26
package org.gvsig.jdk.sun.awt.geom;
27

  
28
import java.awt.geom.PathIterator;
29
import java.util.Enumeration;
30
import java.util.Vector;
31

  
32
public abstract class Crossings {
33
    public static final boolean debug = false;
34

  
35
    int limit = 0;
36
    double yranges[] = new double[10];
37

  
38
    double xlo, ylo, xhi, yhi;
39

  
40
    Crossings(double xlo, double ylo, double xhi, double yhi) {
41
        this.xlo = xlo;
42
        this.ylo = ylo;
43
        this.xhi = xhi;
44
        this.yhi = yhi;
45
    }
46

  
47
    public final double getXLo() {
48
        return xlo;
49
    }
50

  
51
    public final double getYLo() {
52
        return ylo;
53
    }
54

  
55
    public final double getXHi() {
56
        return xhi;
57
    }
58

  
59
    public final double getYHi() {
60
        return yhi;
61
    }
62

  
63
    public abstract void record(double ystart, double yend, int direction);
64

  
65
    public void print() {
66
        System.out.println("Crossings [");
67
        System.out.println("  bounds = ["+ylo+", "+yhi+"]");
68
        for (int i = 0; i < limit; i += 2) {
69
            System.out.println("  ["+yranges[i]+", "+yranges[i+1]+"]");
70
        }
71
        System.out.println("]");
72
    }
73

  
74
    public final boolean isEmpty() {
75
        return (limit == 0);
76
    }
77

  
78
    public abstract boolean covers(double ystart, double yend);
79

  
80
    public static Crossings findCrossings(Vector curves,
81
                                          double xlo, double ylo,
82
                                          double xhi, double yhi)
83
    {
84
        Crossings cross = new EvenOdd(xlo, ylo, xhi, yhi);
85
        Enumeration enum_ = curves.elements();
86
        while (enum_.hasMoreElements()) {
87
            Curve c = (Curve) enum_.nextElement();
88
            if (c.accumulateCrossings(cross)) {
89
                return null;
90
            }
91
        }
92
        if (debug) {
93
            cross.print();
94
        }
95
        return cross;
96
    }
97

  
98
    public static Crossings findCrossings(PathIterator pi,
99
                                          double xlo, double ylo,
100
                                          double xhi, double yhi)
101
    {
102
        Crossings cross;
103
        if (pi.getWindingRule() == pi.WIND_EVEN_ODD) {
104
            cross = new EvenOdd(xlo, ylo, xhi, yhi);
105
        } else {
106
            cross = new NonZero(xlo, ylo, xhi, yhi);
107
        }
108
        // coords array is big enough for holding:
109
        //     coordinates returned from currentSegment (6)
110
        //     OR
111
        //         two subdivided quadratic curves (2+4+4=10)
112
        //         AND
113
        //             0-1 horizontal splitting parameters
114
        //             OR
115
        //             2 parametric equation derivative coefficients
116
        //     OR
117
        //         three subdivided cubic curves (2+6+6+6=20)
118
        //         AND
119
        //             0-2 horizontal splitting parameters
120
        //             OR
121
        //             3 parametric equation derivative coefficients
122
        double coords[] = new double[23];
123
        double movx = 0;
124
        double movy = 0;
125
        double curx = 0;
126
        double cury = 0;
127
        double newx, newy;
128
        while (!pi.isDone()) {
129
            int type = pi.currentSegment(coords);
130
            switch (type) {
131
            case PathIterator.SEG_MOVETO:
132
                if (movy != cury &&
133
                    cross.accumulateLine(curx, cury, movx, movy))
134
                {
135
                    return null;
136
                }
137
                movx = curx = coords[0];
138
                movy = cury = coords[1];
139
                break;
140
            case PathIterator.SEG_LINETO:
141
                newx = coords[0];
142
                newy = coords[1];
143
                if (cross.accumulateLine(curx, cury, newx, newy)) {
144
                    return null;
145
                }
146
                curx = newx;
147
                cury = newy;
148
                break;
149
            case PathIterator.SEG_QUADTO:
150
                newx = coords[2];
151
                newy = coords[3];
152
                if (cross.accumulateQuad(curx, cury, coords)) {
153
                    return null;
154
                }
155
                curx = newx;
156
                cury = newy;
157
                break;
158
            case PathIterator.SEG_CUBICTO:
159
                newx = coords[4];
160
                newy = coords[5];
161
                if (cross.accumulateCubic(curx, cury, coords)) {
162
                    return null;
163
                }
164
                curx = newx;
165
                cury = newy;
166
                break;
167
            case PathIterator.SEG_CLOSE:
168
                if (movy != cury &&
169
                    cross.accumulateLine(curx, cury, movx, movy))
170
                {
171
                    return null;
172
                }
173
                curx = movx;
174
                cury = movy;
175
                break;
176
            }
177
            pi.next();
178
        }
179
        if (movy != cury) {
180
            if (cross.accumulateLine(curx, cury, movx, movy)) {
181
                return null;
182
            }
183
        }
184
        if (debug) {
185
            cross.print();
186
        }
187
        return cross;
188
    }
189

  
190
    public boolean accumulateLine(double x0, double y0,
191
                                  double x1, double y1)
192
    {
193
        if (y0 <= y1) {
194
            return accumulateLine(x0, y0, x1, y1, 1);
195
        } else {
196
            return accumulateLine(x1, y1, x0, y0, -1);
197
        }
198
    }
199

  
200
    public boolean accumulateLine(double x0, double y0,
201
                                  double x1, double y1,
202
                                  int direction)
203
    {
204
        if (yhi <= y0 || ylo >= y1) {
205
            return false;
206
        }
207
        if (x0 >= xhi && x1 >= xhi) {
208
            return false;
209
        }
210
        if (y0 == y1) {
211
            return (x0 >= xlo || x1 >= xlo);
212
        }
213
        double xstart, ystart, xend, yend;
214
        double dx = (x1 - x0);
215
        double dy = (y1 - y0);
216
        if (y0 < ylo) {
217
            xstart = x0 + (ylo - y0) * dx / dy;
218
            ystart = ylo;
219
        } else {
220
            xstart = x0;
221
            ystart = y0;
222
        }
223
        if (yhi < y1) {
224
            xend = x0 + (yhi - y0) * dx / dy;
225
            yend = yhi;
226
        } else {
227
            xend = x1;
228
            yend = y1;
229
        }
230
        if (xstart >= xhi && xend >= xhi) {
231
            return false;
232
        }
233
        if (xstart > xlo || xend > xlo) {
234
            return true;
235
        }
236
        record(ystart, yend, direction);
237
        return false;
238
    }
239

  
240
    private Vector tmp = new Vector();
241

  
242
    public boolean accumulateQuad(double x0, double y0, double coords[]) {
243
        if (y0 < ylo && coords[1] < ylo && coords[3] < ylo) {
244
            return false;
245
        }
246
        if (y0 > yhi && coords[1] > yhi && coords[3] > yhi) {
247
            return false;
248
        }
249
        if (x0 > xhi && coords[0] > xhi && coords[2] > xhi) {
250
            return false;
251
        }
252
        if (x0 < xlo && coords[0] < xlo && coords[2] < xlo) {
253
            if (y0 < coords[3]) {
254
                record(Math.max(y0, ylo), Math.min(coords[3], yhi), 1);
255
            } else if (y0 > coords[3]) {
256
                record(Math.max(coords[3], ylo), Math.min(y0, yhi), -1);
257
            }
258
            return false;
259
        }
260
        Curve.insertQuad(tmp, x0, y0, coords);
261
        Enumeration enum_ = tmp.elements();
262
        while (enum_.hasMoreElements()) {
263
            Curve c = (Curve) enum_.nextElement();
264
            if (c.accumulateCrossings(this)) {
265
                return true;
266
            }
267
        }
268
        tmp.clear();
269
        return false;
270
    }
271

  
272
    public boolean accumulateCubic(double x0, double y0, double coords[]) {
273
        if (y0 < ylo && coords[1] < ylo &&
274
            coords[3] < ylo && coords[5] < ylo)
275
        {
276
            return false;
277
        }
278
        if (y0 > yhi && coords[1] > yhi &&
279
            coords[3] > yhi && coords[5] > yhi)
280
        {
281
            return false;
282
        }
283
        if (x0 > xhi && coords[0] > xhi &&
284
            coords[2] > xhi && coords[4] > xhi)
285
        {
286
            return false;
287
        }
288
        if (x0 < xlo && coords[0] < xlo &&
289
            coords[2] < xlo && coords[4] < xlo)
290
        {
291
            if (y0 <= coords[5]) {
292
                record(Math.max(y0, ylo), Math.min(coords[5], yhi), 1);
293
            } else {
294
                record(Math.max(coords[5], ylo), Math.min(y0, yhi), -1);
295
            }
296
            return false;
297
        }
298
        Curve.insertCubic(tmp, x0, y0, coords);
299
        Enumeration enum_ = tmp.elements();
300
        while (enum_.hasMoreElements()) {
301
            Curve c = (Curve) enum_.nextElement();
302
            if (c.accumulateCrossings(this)) {
303
                return true;
304
            }
305
        }
306
        tmp.clear();
307
        return false;
308
    }
309

  
310
    final static class EvenOdd extends Crossings {
311
        public EvenOdd(double xlo, double ylo, double xhi, double yhi) {
312
            super(xlo, ylo, xhi, yhi);
313
        }
314

  
315
        public final boolean covers(double ystart, double yend) {
316
            return (limit == 2 && yranges[0] <= ystart && yranges[1] >= yend);
317
        }
318

  
319
        public void record(double ystart, double yend, int direction) {
320
            if (ystart >= yend) {
321
                return;
322
            }
323
            int from = 0;
324
            // Quickly jump over all pairs that are completely "above"
325
            while (from < limit && ystart > yranges[from+1]) {
326
                from += 2;
327
            }
328
            int to = from;
329
            while (from < limit) {
330
                double yrlo = yranges[from++];
331
                double yrhi = yranges[from++];
332
                if (yend < yrlo) {
333
                    // Quickly handle insertion of the new range
334
                    yranges[to++] = ystart;
335
                    yranges[to++] = yend;
336
                    ystart = yrlo;
337
                    yend = yrhi;
338
                    continue;
339
                }
340
                // The ranges overlap - sort, collapse, insert, iterate
341
                double yll, ylh, yhl, yhh;
342
                if (ystart < yrlo) {
343
                    yll = ystart;
344
                    ylh = yrlo;
345
                } else {
346
                    yll = yrlo;
347
                    ylh = ystart;
348
                }
349
                if (yend < yrhi) {
350
                    yhl = yend;
351
                    yhh = yrhi;
352
                } else {
353
                    yhl = yrhi;
354
                    yhh = yend;
355
                }
356
                if (ylh == yhl) {
357
                    ystart = yll;
358
                    yend = yhh;
359
                } else {
360
                    if (ylh > yhl) {
361
                        ystart = yhl;
362
                        yhl = ylh;
363
                        ylh = ystart;
364
                    }
365
                    if (yll != ylh) {
366
                        yranges[to++] = yll;
367
                        yranges[to++] = ylh;
368
                    }
369
                    ystart = yhl;
370
                    yend = yhh;
371
                }
372
                if (ystart >= yend) {
373
                    break;
374
                }
375
            }
376
            if (to < from && from < limit) {
377
                System.arraycopy(yranges, from, yranges, to, limit-from);
378
            }
379
            to += (limit-from);
380
            if (ystart < yend) {
381
                if (to >= yranges.length) {
382
                    double newranges[] = new double[to+10];
383
                    System.arraycopy(yranges, 0, newranges, 0, to);
384
                    yranges = newranges;
385
                }
386
                yranges[to++] = ystart;
387
                yranges[to++] = yend;
388
            }
389
            limit = to;
390
        }
391
    }
392

  
393
    final static class NonZero extends Crossings {
394
        private int crosscounts[];
395

  
396
        public NonZero(double xlo, double ylo, double xhi, double yhi) {
397
            super(xlo, ylo, xhi, yhi);
398
            crosscounts = new int[yranges.length / 2];
399
        }
400

  
401
        public final boolean covers(double ystart, double yend) {
402
            int i = 0;
403
            while (i < limit) {
404
                double ylo = yranges[i++];
405
                double yhi = yranges[i++];
406
                if (ystart >= yhi) {
407
                    continue;
408
                }
409
                if (ystart < ylo) {
410
                    return false;
411
                }
412
                if (yend <= yhi) {
413
                    return true;
414
                }
415
                ystart = yhi;
416
            }
417
            return (ystart >= yend);
418
        }
419

  
420
        public void remove(int cur) {
421
            limit -= 2;
422
            int rem = limit - cur;
423
            if (rem > 0) {
424
                System.arraycopy(yranges, cur+2, yranges, cur, rem);
425
                System.arraycopy(crosscounts, cur/2+1,
426
                                 crosscounts, cur/2,
427
                                 rem/2);
428
            }
429
        }
430

  
431
        public void insert(int cur, double lo, double hi, int dir) {
432
            int rem = limit - cur;
433
            double oldranges[] = yranges;
434
            int oldcounts[] = crosscounts;
435
            if (limit >= yranges.length) {
436
                yranges = new double[limit+10];
437
                System.arraycopy(oldranges, 0, yranges, 0, cur);
438
                crosscounts = new int[(limit+10)/2];
439
                System.arraycopy(oldcounts, 0, crosscounts, 0, cur/2);
440
            }
441
            if (rem > 0) {
442
                System.arraycopy(oldranges, cur, yranges, cur+2, rem);
443
                System.arraycopy(oldcounts, cur/2,
444
                                 crosscounts, cur/2+1,
445
                                 rem/2);
446
            }
447
            yranges[cur+0] = lo;
448
            yranges[cur+1] = hi;
449
            crosscounts[cur/2] = dir;
450
            limit += 2;
451
        }
452

  
453
        public void record(double ystart, double yend, int direction) {
454
            if (ystart >= yend) {
455
                return;
456
            }
457
            int cur = 0;
458
            // Quickly jump over all pairs that are completely "above"
459
            while (cur < limit && ystart > yranges[cur+1]) {
460
                cur += 2;
461
            }
462
            if (cur < limit) {
463
                int rdir = crosscounts[cur/2];
464
                double yrlo = yranges[cur+0];
465
                double yrhi = yranges[cur+1];
466
                if (yrhi == ystart && rdir == direction) {
467
                    // Remove the range from the list and collapse it
468
                    // into the range being inserted.  Note that the
469
                    // new combined range may overlap the following range
470
                    // so we must not simply combine the ranges in place
471
                    // unless we are at the last range.
472
                    if (cur+2 == limit) {
473
                        yranges[cur+1] = yend;
474
                        return;
475
                    }
476
                    remove(cur);
477
                    ystart = yrlo;
478
                    rdir = crosscounts[cur/2];
479
                    yrlo = yranges[cur+0];
480
                    yrhi = yranges[cur+1];
481
                }
482
                if (yend < yrlo) {
483
                    // Just insert the new range at the current location
484
                    insert(cur, ystart, yend, direction);
485
                    return;
486
                }
487
                if (yend == yrlo && rdir == direction) {
488
                    // Just prepend the new range to the current one
489
                    yranges[cur] = ystart;
490
                    return;
491
                }
492
                // The ranges must overlap - (yend > yrlo && yrhi > ystart)
493
                if (ystart < yrlo) {
494
                    insert(cur, ystart, yrlo, direction);
495
                    cur += 2;
496
                    ystart = yrlo;
497
                } else if (yrlo < ystart) {
498
                    insert(cur, yrlo, ystart, rdir);
499
                    cur += 2;
500
                    yrlo = ystart;
501
                }
502
                // assert(yrlo == ystart);
503
                int newdir = rdir + direction;
504
                double newend = Math.min(yend, yrhi);
505
                if (newdir == 0) {
506
                    remove(cur);
507
                } else {
508
                    crosscounts[cur/2] = newdir;
509
                    yranges[cur++] = ystart;
510
                    yranges[cur++] = newend;
511
                }
512
                ystart = yrlo = newend;
513
                if (yrlo < yrhi) {
514
                    insert(cur, yrlo, yrhi, rdir);
515
                }
516
            }
517
            if (ystart < yend) {
518
                insert(cur, ystart, yend, direction);
519
            }
520
        }
521
    }
522
}
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/java/org/gvsig/jdk/sun/awt/geom/Order0.java
1
/*
2
 * Copyright 1998 Sun Microsystems, Inc.  All Rights Reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Sun designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Sun in the LICENSE file that accompanied this code.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22
 * CA 95054 USA or visit www.sun.com if you need additional information or
23
 * have any questions.
24
 */
25

  
26
package org.gvsig.jdk.sun.awt.geom;
27

  
28
import java.awt.geom.PathIterator;
29
import java.awt.geom.Rectangle2D;
30

  
31
final class Order0 extends Curve {
32
    private double x;
33
    private double y;
34

  
35
    Order0(double x, double y) {
36
        super(INCREASING);
37
        this.x = x;
38
        this.y = y;
39
    }
40

  
41
    public int getOrder() {
42
        return 0;
43
    }
44

  
45
    public double getXTop() {
46
        return x;
47
    }
48

  
49
    public double getYTop() {
50
        return y;
51
    }
52

  
53
    public double getXBot() {
54
        return x;
55
    }
56

  
57
    public double getYBot() {
58
        return y;
59
    }
60

  
61
    public double getXMin() {
62
        return x;
63
    }
64

  
65
    public double getXMax() {
66
        return x;
67
    }
68

  
69
    public double getX0() {
70
        return x;
71
    }
72

  
73
    public double getY0() {
74
        return y;
75
    }
76

  
77
    public double getX1() {
78
        return x;
79
    }
80

  
81
    public double getY1() {
82
        return y;
83
    }
84

  
85
    public double XforY(double y) {
86
        return y;
87
    }
88

  
89
    public double TforY(double y) {
90
        return 0;
91
    }
92

  
93
    public double XforT(double t) {
94
        return x;
95
    }
96

  
97
    public double YforT(double t) {
98
        return y;
99
    }
100

  
101
    public double dXforT(double t, int deriv) {
102
        return 0;
103
    }
104

  
105
    public double dYforT(double t, int deriv) {
106
        return 0;
107
    }
108

  
109
    public double nextVertical(double t0, double t1) {
110
        return t1;
111
    }
112

  
113
    public int crossingsFor(double x, double y) {
114
        return 0;
115
    }
116

  
117
    public boolean accumulateCrossings(Crossings c) {
118
        return (x > c.getXLo() &&
119
                x < c.getXHi() &&
120
                y > c.getYLo() &&
121
                y < c.getYHi());
122
    }
123

  
124
    public void enlarge(Rectangle2D r) {
125
        r.add(x, y);
126
    }
127

  
128
    public Curve getSubCurve(double ystart, double yend, int dir) {
129
        return this;
130
    }
131

  
132
    public Curve getReversedCurve() {
133
        return this;
134
    }
135

  
136
    public int getSegment(double coords[]) {
137
        coords[0] = x;
138
        coords[1] = y;
139
        return PathIterator.SEG_MOVETO;
140
    }
141
}
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/java/org/gvsig/jdk/sun/awt/geom/Order1.java
1
/*
2
 * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Sun designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Sun in the LICENSE file that accompanied this code.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22
 * CA 95054 USA or visit www.sun.com if you need additional information or
23
 * have any questions.
24
 */
25

  
26
package org.gvsig.jdk.sun.awt.geom;
27

  
28
import java.awt.geom.PathIterator;
29
import java.awt.geom.Rectangle2D;
30

  
31
final class Order1 extends Curve {
32
    private double x0;
33
    private double y0;
34
    private double x1;
35
    private double y1;
36
    private double xmin;
37
    private double xmax;
38

  
39
    Order1(double x0, double y0,
40
                  double x1, double y1,
41
                  int direction)
42
    {
43
        super(direction);
44
        this.x0 = x0;
45
        this.y0 = y0;
46
        this.x1 = x1;
47
        this.y1 = y1;
48
        if (x0 < x1) {
49
            this.xmin = x0;
50
            this.xmax = x1;
51
        } else {
52
            this.xmin = x1;
53
            this.xmax = x0;
54
        }
55
    }
56

  
57
    public int getOrder() {
58
        return 1;
59
    }
60

  
61
    public double getXTop() {
62
        return x0;
63
    }
64

  
65
    public double getYTop() {
66
        return y0;
67
    }
68

  
69
    public double getXBot() {
70
        return x1;
71
    }
72

  
73
    public double getYBot() {
74
        return y1;
75
    }
76

  
77
    public double getXMin() {
78
        return xmin;
79
    }
80

  
81
    public double getXMax() {
82
        return xmax;
83
    }
84

  
85
    public double getX0() {
86
        return (direction == INCREASING) ? x0 : x1;
87
    }
88

  
89
    public double getY0() {
90
        return (direction == INCREASING) ? y0 : y1;
91
    }
92

  
93
    public double getX1() {
94
        return (direction == DECREASING) ? x0 : x1;
95
    }
96

  
97
    public double getY1() {
98
        return (direction == DECREASING) ? y0 : y1;
99
    }
100

  
101
    public double XforY(double y) {
102
        if (x0 == x1 || y <= y0) {
103
            return x0;
104
        }
105
        if (y >= y1) {
106
            return x1;
107
        }
108
        // assert(y0 != y1); /* No horizontal lines... */
109
        return (x0 + (y - y0) * (x1 - x0) / (y1 - y0));
110
    }
111

  
112
    public double TforY(double y) {
113
        if (y <= y0) {
114
            return 0;
115
        }
116
        if (y >= y1) {
117
            return 1;
118
        }
119
        return (y - y0) / (y1 - y0);
120
    }
121

  
122
    public double XforT(double t) {
123
        return x0 + t * (x1 - x0);
124
    }
125

  
126
    public double YforT(double t) {
127
        return y0 + t * (y1 - y0);
128
    }
129

  
130
    public double dXforT(double t, int deriv) {
131
        switch (deriv) {
132
        case 0:
133
            return x0 + t * (x1 - x0);
134
        case 1:
135
            return (x1 - x0);
136
        default:
137
            return 0;
138
        }
139
    }
140

  
141
    public double dYforT(double t, int deriv) {
142
        switch (deriv) {
143
        case 0:
144
            return y0 + t * (y1 - y0);
145
        case 1:
146
            return (y1 - y0);
147
        default:
148
            return 0;
149
        }
150
    }
151

  
152
    public double nextVertical(double t0, double t1) {
153
        return t1;
154
    }
155

  
156
    public boolean accumulateCrossings(Crossings c) {
157
        double xlo = c.getXLo();
158
        double ylo = c.getYLo();
159
        double xhi = c.getXHi();
160
        double yhi = c.getYHi();
161
        if (xmin >= xhi) {
162
            return false;
163
        }
164
        double xstart, ystart, xend, yend;
165
        if (y0 < ylo) {
166
            if (y1 <= ylo) {
167
                return false;
168
            }
169
            ystart = ylo;
170
            xstart = XforY(ylo);
171
        } else {
172
            if (y0 >= yhi) {
173
                return false;
174
            }
175
            ystart = y0;
176
            xstart = x0;
177
        }
178
        if (y1 > yhi) {
179
            yend = yhi;
180
            xend = XforY(yhi);
181
        } else {
182
            yend = y1;
183
            xend = x1;
184
        }
185
        if (xstart >= xhi && xend >= xhi) {
186
            return false;
187
        }
188
        if (xstart > xlo || xend > xlo) {
189
            return true;
190
        }
191
        c.record(ystart, yend, direction);
192
        return false;
193
    }
194

  
195
    public void enlarge(Rectangle2D r) {
196
        r.add(x0, y0);
197
        r.add(x1, y1);
198
    }
199

  
200
    public Curve getSubCurve(double ystart, double yend, int dir) {
201
        if (ystart == y0 && yend == y1) {
202
            return getWithDirection(dir);
203
        }
204
        if (x0 == x1) {
205
            return new Order1(x0, ystart, x1, yend, dir);
206
        }
207
        double num = x0 - x1;
208
        double denom = y0 - y1;
209
        double xstart = (x0 + (ystart - y0) * num / denom);
210
        double xend = (x0 + (yend - y0) * num / denom);
211
        return new Order1(xstart, ystart, xend, yend, dir);
212
    }
213

  
214
    public Curve getReversedCurve() {
215
        return new Order1(x0, y0, x1, y1, -direction);
216
    }
217

  
218
    public int compareTo(Curve other, double yrange[]) {
219
        if (!(other instanceof Order1)) {
220
            return super.compareTo(other, yrange);
221
        }
222
        Order1 c1 = (Order1) other;
223
        if (yrange[1] <= yrange[0]) {
224
            throw new InternalError("yrange already screwed up...");
225
        }
226
        yrange[1] = Math.min(Math.min(yrange[1], y1), c1.y1);
227
        if (yrange[1] <= yrange[0]) {
228
            throw new InternalError("backstepping from "+yrange[0]+" to "+yrange[1]);
229
        }
230
        if (xmax <= c1.xmin) {
231
            return (xmin == c1.xmax) ? 0 : -1;
232
        }
233
        if (xmin >= c1.xmax) {
234
            return 1;
235
        }
236
        /*
237
         * If "this" is curve A and "other" is curve B, then...
238
         * xA(y) = x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
239
         * xB(y) = x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
240
         * xA(y) == xB(y)
241
         * x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
242
         *    == x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
243
         * 0 == x0A (y1A - y0A) (y1B - y0B) + (y - y0A) (x1A - x0A) (y1B - y0B)
244
         *    - x0B (y1A - y0A) (y1B - y0B) - (y - y0B) (x1B - x0B) (y1A - y0A)
245
         * 0 == (x0A - x0B) (y1A - y0A) (y1B - y0B)
246
         *    + (y - y0A) (x1A - x0A) (y1B - y0B)
247
         *    - (y - y0B) (x1B - x0B) (y1A - y0A)
248
         * If (dxA == x1A - x0A), etc...
249
         * 0 == (x0A - x0B) * dyA * dyB
250
         *    + (y - y0A) * dxA * dyB
251
         *    - (y - y0B) * dxB * dyA
252
         * 0 == (x0A - x0B) * dyA * dyB
253
         *    + y * dxA * dyB - y0A * dxA * dyB
254
         *    - y * dxB * dyA + y0B * dxB * dyA
255
         * 0 == (x0A - x0B) * dyA * dyB
256
         *    + y * dxA * dyB - y * dxB * dyA
257
         *    - y0A * dxA * dyB + y0B * dxB * dyA
258
         * 0 == (x0A - x0B) * dyA * dyB
259
         *    + y * (dxA * dyB - dxB * dyA)
260
         *    - y0A * dxA * dyB + y0B * dxB * dyA
261
         * y == ((x0A - x0B) * dyA * dyB
262
         *       - y0A * dxA * dyB + y0B * dxB * dyA)
263
         *    / (-(dxA * dyB - dxB * dyA))
264
         * y == ((x0A - x0B) * dyA * dyB
265
         *       - y0A * dxA * dyB + y0B * dxB * dyA)
266
         *    / (dxB * dyA - dxA * dyB)
267
         */
268
        double dxa = x1 - x0;
269
        double dya = y1 - y0;
270
        double dxb = c1.x1 - c1.x0;
271
        double dyb = c1.y1 - c1.y0;
272
        double denom = dxb * dya - dxa * dyb;
273
        double y;
274
        if (denom != 0) {
275
            double num = ((x0 - c1.x0) * dya * dyb
276
                          - y0 * dxa * dyb
277
                          + c1.y0 * dxb * dya);
278
            y = num / denom;
279
            if (y <= yrange[0]) {
280
                // intersection is above us
281
                // Use bottom-most common y for comparison
282
                y = Math.min(y1, c1.y1);
283
            } else {
284
                // intersection is below the top of our range
285
                if (y < yrange[1]) {
286
                    // If intersection is in our range, adjust valid range
287
                    yrange[1] = y;
288
                }
289
                // Use top-most common y for comparison
290
                y = Math.max(y0, c1.y0);
291
            }
292
        } else {
293
            // lines are parallel, choose any common y for comparison
294
            // Note - prefer an endpoint for speed of calculating the X
295
            // (see shortcuts in Order1.XforY())
296
            y = Math.max(y0, c1.y0);
297
        }
298
        return orderof(XforY(y), c1.XforY(y));
299
    }
300

  
301
    public int getSegment(double coords[]) {
302
        if (direction == INCREASING) {
303
            coords[0] = x1;
304
            coords[1] = y1;
305
        } else {
306
            coords[0] = x0;
307
            coords[1] = y0;
308
        }
309
        return PathIterator.SEG_LINETO;
310
    }
311
}
org.gvsig.jdk/tags/org.gvsig.jdk-1.0.2/org.gvsig.jdk.v1_6/src/main/java/org/gvsig/jdk/sun/awt/geom/Order2.java
1
/*
2
 * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Sun designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Sun in the LICENSE file that accompanied this code.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22
 * CA 95054 USA or visit www.sun.com if you need additional information or
23
 * have any questions.
24
 */
25

  
26
package org.gvsig.jdk.sun.awt.geom;
27

  
28
import java.awt.geom.PathIterator;
29
import java.awt.geom.Rectangle2D;
30
import java.util.Vector;
31

  
32
final class Order2 extends Curve {
33
    private double x0;
34
    private double y0;
35
    private double cx0;
36
    private double cy0;
37
    private double x1;
38
    private double y1;
39
    private double xmin;
40
    private double xmax;
41

  
42
    private double xcoeff0;
43
    private double xcoeff1;
44
    private double xcoeff2;
45
    private double ycoeff0;
46
    private double ycoeff1;
47
    private double ycoeff2;
48

  
49
    public static void insert(Vector curves, double tmp[],
50
                              double x0, double y0,
51
                              double cx0, double cy0,
52
                              double x1, double y1,
53
                              int direction)
54
    {
55
        int numparams = getHorizontalParams(y0, cy0, y1, tmp);
56
        if (numparams == 0) {
57
            // We are using addInstance here to avoid inserting horisontal
58
            // segments
59
            addInstance(curves, x0, y0, cx0, cy0, x1, y1, direction);
60
            return;
61
        }
62
        // assert(numparams == 1);
63
        double t = tmp[0];
64
        tmp[0] = x0;  tmp[1] = y0;
65
        tmp[2] = cx0; tmp[3] = cy0;
66
        tmp[4] = x1;  tmp[5] = y1;
67
        split(tmp, 0, t);
68
        int i0 = (direction == INCREASING)? 0 : 4;
69
        int i1 = 4 - i0;
70
        addInstance(curves, tmp[i0], tmp[i0 + 1], tmp[i0 + 2], tmp[i0 + 3],
71
                    tmp[i0 + 4], tmp[i0 + 5], direction);
72
        addInstance(curves, tmp[i1], tmp[i1 + 1], tmp[i1 + 2], tmp[i1 + 3],
73
                    tmp[i1 + 4], tmp[i1 + 5], direction);
74
    }
75

  
76
    public static void addInstance(Vector curves,
77
                                   double x0, double y0,
78
                                   double cx0, double cy0,
79
                                   double x1, double y1,
80
                                   int direction) {
81
        if (y0 > y1) {
82
            curves.add(new Order2(x1, y1, cx0, cy0, x0, y0, -direction));
83
        } else if (y1 > y0) {
84
            curves.add(new Order2(x0, y0, cx0, cy0, x1, y1, direction));
85
        }
86
    }
87

  
88
    /*
89
     * Return the count of the number of horizontal sections of the
90
     * specified quadratic Bezier curve.  Put the parameters for the
91
     * horizontal sections into the specified <code>ret</code> array.
92
     * <p>
93
     * If we examine the parametric equation in t, we have:
94
     *     Py(t) = C0*(1-t)^2 + 2*CP*t*(1-t) + C1*t^2
95
     *           = C0 - 2*C0*t + C0*t^2 + 2*CP*t - 2*CP*t^2 + C1*t^2
96
     *           = C0 + (2*CP - 2*C0)*t + (C0 - 2*CP + C1)*t^2
97
     *     Py(t) = (C0 - 2*CP + C1)*t^2 + (2*CP - 2*C0)*t + (C0)
98
     * If we take the derivative, we get:
99
     *     Py(t) = At^2 + Bt + C
100
     *     dPy(t) = 2At + B = 0
101
     *     2*(C0 - 2*CP + C1)t + 2*(CP - C0) = 0
102
     *     2*(C0 - 2*CP + C1)t = 2*(C0 - CP)
103
     *     t = 2*(C0 - CP) / 2*(C0 - 2*CP + C1)
104
     *     t = (C0 - CP) / (C0 - CP + C1 - CP)
105
     * Note that this method will return 0 if the equation is a line,
106
     * which is either always horizontal or never horizontal.
107
     * Completely horizontal curves need to be eliminated by other
108
     * means outside of this method.
109
     */
110
    public static int getHorizontalParams(double c0, double cp, double c1,
111
                                          double ret[]) {
112
        if (c0 <= cp && cp <= c1) {
113
            return 0;
114
        }
115
        c0 -= cp;
116
        c1 -= cp;
117
        double denom = c0 + c1;
118
        // If denom == 0 then cp == (c0+c1)/2 and we have a line.
119
        if (denom == 0) {
120
            return 0;
121
        }
122
        double t = c0 / denom;
123
        // No splits at t==0 and t==1
124
        if (t <= 0 || t >= 1) {
125
            return 0;
126
        }
127
        ret[0] = t;
128
        return 1;
129
    }
130

  
131
    /*
132
     * Split the quadratic Bezier stored at coords[pos...pos+5] representing
133
     * the paramtric range [0..1] into two subcurves representing the
134
     * parametric subranges [0..t] and [t..1].  Store the results back
135
     * into the array at coords[pos...pos+5] and coords[pos+4...pos+9].
136
     */
137
    public static void split(double coords[], int pos, double t) {
138
        double x0, y0, cx, cy, x1, y1;
139
        coords[pos+8] = x1 = coords[pos+4];
140
        coords[pos+9] = y1 = coords[pos+5];
141
        cx = coords[pos+2];
142
        cy = coords[pos+3];
143
        x1 = cx + (x1 - cx) * t;
144
        y1 = cy + (y1 - cy) * t;
145
        x0 = coords[pos+0];
146
        y0 = coords[pos+1];
147
        x0 = x0 + (cx - x0) * t;
148
        y0 = y0 + (cy - y0) * t;
149
        cx = x0 + (x1 - x0) * t;
150
        cy = y0 + (y1 - y0) * t;
151
        coords[pos+2] = x0;
152
        coords[pos+3] = y0;
153
        coords[pos+4] = cx;
154
        coords[pos+5] = cy;
155
        coords[pos+6] = x1;
156
        coords[pos+7] = y1;
157
    }
158

  
159
    Order2(double x0, double y0,
160
                  double cx0, double cy0,
161
                  double x1, double y1,
162
                  int direction)
163
    {
164
        super(direction);
165
        // REMIND: Better accuracy in the root finding methods would
166
        //  ensure that cy0 is in range.  As it stands, it is never
167
        //  more than "1 mantissa bit" out of range...
168
        if (cy0 < y0) {
169
            cy0 = y0;
170
        } else if (cy0 > y1) {
171
            cy0 = y1;
172
        }
173
        this.x0 = x0;
174
        this.y0 = y0;
175
        this.cx0 = cx0;
176
        this.cy0 = cy0;
177
        this.x1 = x1;
178
        this.y1 = y1;
179
        xmin = Math.min(Math.min(x0, x1), cx0);
180
        xmax = Math.max(Math.max(x0, x1), cx0);
181
        xcoeff0 = x0;
182
        xcoeff1 = cx0 + cx0 - x0 - x0;
183
        xcoeff2 = x0 - cx0 - cx0 + x1;
184
        ycoeff0 = y0;
185
        ycoeff1 = cy0 + cy0 - y0 - y0;
186
        ycoeff2 = y0 - cy0 - cy0 + y1;
187
    }
188

  
189
    public int getOrder() {
190
        return 2;
191
    }
192

  
193
    public double getXTop() {
194
        return x0;
195
    }
196

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff