in modules/awt/src/main/java/common/java/awt/BasicStroke.java [794:955]
void addCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
double x12 = x1 - x2;
double y12 = y1 - y2;
double x23 = x2 - x3;
double y23 = y2 - y3;
double x34 = x3 - x4;
double y34 = y3 - y4;
double l12 = Math.sqrt(x12 * x12 + y12 * y12);
double l23 = Math.sqrt(x23 * x23 + y23 * y23);
double l34 = Math.sqrt(x34 * x34 + y34 * y34);
// All edges are zero
if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
addLine(x1, y1, x4, y4, false);
return;
}
// One zero edge
if (l12 == 0.0 && l23 == 0.0) {
addLine(x3, y3, x4, y4, false);
return;
}
if (l23 == 0.0 && l34 == 0.0) {
addLine(x1, y1, x2, y2, false);
return;
}
if (l12 == 0.0 && l34 == 0.0) {
addLine(x2, y2, x3, y3, false);
return;
}
double w, mx1, my1, mx4, my4;
boolean onLine;
if (l12 == 0.0) {
w = w2 / l23;
mx1 = y23 * w;
my1 = - x23 * w;
w = w2 / l34;
mx4 = y34 * w;
my4 = - x34 * w;
onLine = - x23 * y34 + y23 * x34 == 0.0; // sin3
} else
if (l34 == 0.0) {
w = w2 / l12;
mx1 = y12 * w;
my1 = - x12 * w;
w = w2 / l23;
mx4 = y23 * w;
my4 = - x23 * w;
onLine = - x12 * y23 + y12 * x23 == 0.0; // sin2
} else {
w = w2 / l12;
mx1 = y12 * w;
my1 = - x12 * w;
w = w2 / l34;
mx4 = y34 * w;
my4 = - x34 * w;
if (l23 == 0.0) {
onLine = - x12 * y34 + y12 * x34 == 0.0;
} else {
onLine =
- x12 * y34 + y12 * x34 == 0.0 &&
- x12 * y23 + y12 * x23 == 0.0 && // sin2
- x23 * y34 + y23 * x34 == 0.0; // sin3
}
}
double lx1 = x1 + mx1;
double ly1 = y1 + my1;
double rx1 = x1 - mx1;
double ry1 = y1 - my1;
if (checkMove) {
if (isMove) {
isMove = false;
lp.moveTo(lx1, ly1);
rp.moveTo(rx1, ry1);
} else {
addJoin(lp, x1, y1, lx1, ly1, true);
addJoin(rp, x1, y1, rx1, ry1, false);
}
}
if (onLine) {
if ((x1 == x2 && y1 < y2) || x1 < x2) {
l12 = -l12;
}
if ((x2 == x3 && y2 < y3) || x2 < x3) {
l23 = -l23;
}
if ((x3 == x4 && y3 < y4) || x3 < x4) {
l34 = -l34;
}
double d = l23 * l23 - l12 * l34;
double roots[] = new double[3];
int rc = 0;
if (d == 0.0) {
double t = (l12 - l23) / (l12 + l34 - l23 - l23);
if (0.0 < t && t < 1.0) {
roots[rc++] = t;
}
} else
if (d > 0.0) {
d = Math.sqrt(d);
double z = l12 + l34 - l23 - l23;
double t;
t = (l12 - l23 + d) / z;
if (0.0 < t && t < 1.0) {
roots[rc++] = t;
}
t = (l12 - l23 - d) / z;
if (0.0 < t && t < 1.0) {
roots[rc++] = t;
}
}
if (rc > 0) {
// Sort roots
if (rc == 2 && roots[0] > roots[1]) {
double tmp = roots[0];
roots[0] = roots[1];
roots[1] = tmp;
}
roots[rc++] = 1.0;
double ax = - x34 - x12 + x23 + x23;
double ay = - y34 - y12 + y23 + y23;
double bx = 3.0 * (- x23 + x12);
double by = 3.0 * (- y23 + y12);
double cx = 3.0 * (- x12);
double cy = 3.0 * (- y12);
double xPrev = x1;
double yPrev = y1;
for(int i = 0; i < rc; i++) {
double t = roots[i];
double px = t * (t * (t * ax + bx) + cx) + x1;
double py = t * (t * (t * ay + by) + cy) + y1;
double px1 = (xPrev + px) / 2.0;
double py1 = (yPrev + py) / 2.0;
lp.cubicTo(px1 + mx1, py1 + my1, px1 + mx1, py1 + my1, px + mx1, py + my1);
rp.cubicTo(px1 - mx1, py1 - my1, px1 - mx1, py1 - my1, px - mx1, py - my1);
if (i < rc - 1) {
lp.lineTo(px - mx1, py - my1);
rp.lineTo(px + mx1, py + my1);
}
xPrev = px;
yPrev = py;
mx1 = - mx1;
my1 = - my1;
}
} else {
lp.cubicTo(x2 + mx1, y2 + my1, x3 + mx4, y3 + my4, x4 + mx4, y4 + my4);
rp.cubicTo(x2 - mx1, y2 - my1, x3 - mx4, y3 - my4, x4 - mx4, y4 - my4);
}
} else {
addSubCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0);
}
}