private static int drawTail()

in packages/serverless-workflow-diagram-editor/lienzo-core/src/main/java/com/ait/lienzo/client/core/shape/OrthogonalPolyLine.java [460:643]


    private static int drawTail(Point2DArray points, NFastDoubleArray buffer, Direction lastDirection, Direction tailDirection, double correction, final OrthogonalPolyLine pline, double p0x, double p0y, double p1x, double p1y, boolean write) {
        double tailOffset = pline.getTailOffset();

        double distance = 0;
        Point2D p1 = points.get(points.size() - 1);

        // correct for tailOffset
        if (tailOffset > 0) {
            if (!write) {
                p1 = p1.copy();
            }
            correctEndWithOffset(tailOffset, tailDirection, p1);
            p1x = p1.getX();
            p1y = p1.getY();
        }

        // correct for correction
        if (correction > 0) {
            // must do this off a cloned Point2D, as we still need the p1, for the last part of the line at the end.
            Point2D p1Copy = p1.copy();
            correctEndWithOffset(correction, tailDirection, p1Copy);
            p1x = p1Copy.getX();
            p1y = p1Copy.getY();
        }

        final double dx = (p1x - p0x);
        final double dy = (p1y - p0y);

        int corners = 0;

        boolean behind = false;

        switch (tailDirection) {
            case NORTH:
                behind = dy < 0;
                break;
            case SOUTH:
                behind = dy > 0;
                break;
            case WEST:
                behind = dx < 0;
                break;
            case EAST:
                behind = dx > 0;
                break;
            case NONE:
                // do nothing as NONE is explicitey handled at the end
                break;
            default:
                throw new IllegalStateException("Invalid Direction " + tailDirection);
        }
        double x = p0x;

        double y = p0y;

        double break_distance_ratio = (Math.abs(dx) / Math.abs(dy)) * 2;
        break_distance_ratio = Math.max(break_distance_ratio, 1.5d);

        if (behind) {
            // means p0 is behind.
            switch (tailDirection) {
                case NORTH:
                case SOUTH:
                    if ((lastDirection == NORTH && tailDirection == SOUTH) ||
                            (lastDirection == SOUTH && tailDirection == NORTH) ||
                            (dx > 0 && lastDirection == EAST) ||
                            (dx < 0 && lastDirection == WEST)) {
                        // A mid point is needed to ensure an attractive line is drawn.
                        x = p0x + (dx / break_distance_ratio);
                        addPoint(buffer, x, y, write);

                        if (lastDirection == NORTH || lastDirection == SOUTH) {
                            corners++;
                        }
                    }

                    y = p1y;
                    addPoint(buffer, x, y, write);
                    if (lastDirection != tailDirection) {
                        corners++;
                    }

                    x = p1x;
                    addPoint(buffer, x, y, write);
                    corners++;

                    y = p1.getY();
                    addPoint(buffer, x, y, write);
                    corners++;
                    break;
                case WEST:
                case EAST:
                    if ((lastDirection == WEST && tailDirection == EAST) ||
                            (lastDirection == EAST && tailDirection == WEST) ||
                            (dy > 0 && lastDirection == SOUTH) ||
                            (dy < 0 && lastDirection == NORTH)) {
                        // A mid point is needed to ensure an attrictive line is drawn.
                        y = p0y + (dy / break_distance_ratio);
                        addPoint(buffer, x, y, write);

                        if (lastDirection == EAST || lastDirection == WEST) {
                            corners++;
                        }
                    }

                    x = p1x;
                    addPoint(buffer, x, y, write);
                    if (lastDirection != tailDirection) {
                        corners++;
                    }

                    y = p1y;
                    addPoint(buffer, x, y, write);
                    corners++;

                    x = p1.getX();
                    addPoint(buffer, x, y, write);
                    corners++;
                    break;
                default:
                    throw new IllegalStateException("Invalid Direction " + tailDirection);
            }
        } else {
            // means p0 is in front
            switch (tailDirection) {
                case NORTH:
                case SOUTH:
                    if ((lastDirection == NORTH && tailDirection == SOUTH) ||
                            (lastDirection == SOUTH && tailDirection == NORTH) ||
                            (dx > 0 && lastDirection == WEST) ||
                            (dx < 0 && lastDirection == EAST)) {
                        // A mid point is needed to ensure an attrictive line is drawn.
                        y = p0y + (dy / break_distance_ratio);
                        addPoint(buffer, x, y, write);

                        if (lastDirection == EAST || lastDirection == WEST) {
                            lastDirection = (dy < 0) ? NORTH : SOUTH;
                            corners++;
                        }
                    }

                    x = p1x;
                    addPoint(buffer, x, y, write);
                    if (lastDirection == NORTH || lastDirection == SOUTH) {
                        corners++;
                    }

                    y = p1.getY();
                    addPoint(buffer, x, y, write);
                    corners++;
                    break;
                case WEST:
                case EAST:
                    if ((lastDirection == WEST && tailDirection == EAST) ||
                            (lastDirection == EAST && tailDirection == WEST) ||
                            (dy > 0 && lastDirection == NORTH) ||
                            (dy < 0 && lastDirection == SOUTH)) {
                        // A mid point is needed to ensure an attrictive line is drawn.
                        x = p0x + (dx / break_distance_ratio);
                        addPoint(buffer, x, y, write);

                        if (lastDirection == NORTH || lastDirection == SOUTH) {
                            lastDirection = (dx < 0) ? WEST : EAST;
                            corners++;
                        }
                    }

                    y = p1y;
                    addPoint(buffer, x, y, write);
                    if (lastDirection == EAST || lastDirection == WEST) {
                        corners++;
                    }

                    x = p1.getX();
                    addPoint(buffer, x, y, write);
                    corners++;
                    break;
                default:
                    throw new IllegalStateException("Invalid Direction " + tailDirection);
            }
        }

        return corners;
    }