void addCubic()

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);
        }
    }