1
2 package org.freehep.graphicsio;
3
4 import java.awt.geom.Point2D;
5 import java.io.IOException;
6 import java.util.Stack;
7
8
9
10
11
12
13
14
15
16 public abstract class CubicToLinePathConstructor extends
17 QuadToCubicPathConstructor {
18
19 private double resolution;
20
21 protected CubicToLinePathConstructor() {
22 this(0.025);
23 }
24
25 protected CubicToLinePathConstructor(double resolution) {
26 this.resolution = Math.abs(resolution);
27 }
28
29 public void cubic(double x1, double y1, double x2, double y2, double x3,
30 double y3) throws IOException {
31
32
33 Stack
34
35
36 Point2D p0 = new Point2D.Double(currentX, currentY);
37 Point2D p1 = new Point2D.Double(x1, y1);
38 Point2D p2 = new Point2D.Double(x2, y2);
39 Point2D p3 = new Point2D.Double(x3, y3);
40
41
42 Stack
43 temps.push(new ControlSet(p0, p1, p2, p3));
44
45 while (!temps.empty()) {
46 ControlSet control = (ControlSet) temps.pop();
47 if (control.breadth() > resolution) {
48 temps.push(control);
49 temps.push(control.bisect());
50 } else {
51 controls.push(control);
52 }
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 while (!controls.empty()) {
71 Point2D p = ((ControlSet)controls.pop()).getPoint();
72 line(p.getX(), p.getY());
73
74 }
75
76
77 super.cubic(x1, y1, x2, y2, x3, y3);
78 }
79
80 class ControlSet {
81 private Point2D point0;
82
83 private Point2D point1;
84
85 private Point2D point2;
86
87 private Point2D point3;
88
89 public ControlSet(Point2D p0, Point2D p1, Point2D p2, Point2D p3) {
90 point0 = p0;
91 point1 = p1;
92 point2 = p2;
93 point3 = p3;
94 }
95
96 public double breadth() {
97 double f0 = point0.getX();
98 double f4 = point0.getY();
99 double f1 = point1.getX();
100 double f5 = point1.getY();
101 double f2 = point2.getX();
102 double f6 = point2.getY();
103 double f3 = point3.getX();
104 double f7 = point3.getY();
105 if ((Math.abs(f0 - f3) < resolution)
106 && (Math.abs(f4 - f7) < resolution)) {
107
108 double f8 = Math.abs(f1 - f0) + Math.abs(f5 - f4);
109 double f10 = Math.abs(f2 - f0) + Math.abs(f6 - f4);
110 return Math.max(f10, f8);
111
112 } else {
113
114 double d0 = f4 - f7;
115 double d1 = f3 - f0;
116 double f12 = Math.sqrt(d0 * d0 + d1 * d1);
117 double d2 = f3 * f4 - f0 * f7;
118 double f9 = Math.abs((d0 * f2 + d1 * f6) - d2) / f12;
119 double f11 = Math.abs((d0 * f1 + d1 * f5) - d2) / f12;
120 return Math.max(f9, f11);
121 }
122 }
123
124 public ControlSet bisect() {
125 Point2D p0 = average(point0, point1);
126 Point2D p1 = average(point1, point2);
127 Point2D p2 = average(point2, point3);
128 Point2D p3 = average(p0, p1);
129 Point2D p4 = average(p1, p2);
130 Point2D p5 = average(p3, p4);
131 ControlSet controlset = new ControlSet(p5, p4, p2, point3);
132 point1 = p0;
133 point2 = p3;
134 point3 = p5;
135 return controlset;
136 }
137
138 public Point2D average(Point2D p1, Point2D p2) {
139 return new Point2D.Double((p1.getX() + p2.getX()) / 2.0,
140 (p1.getY() + p2.getY()) / 2.0);
141 }
142
143 public Point2D getPoint() {
144 return point3;
145 }
146 }
147
148 }