Newer
Older
AlgebraicDataflowArchitectureModel / AlgebraicDataflowArchitectureModel / src / models / dependencyModel / mxInterfacePerimeter.java
package models.dependencyModel;

import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxPerimeter;
import com.mxgraph.view.mxCellState;
import com.mxgraph.util.mxPoint;

public class mxInterfacePerimeter implements mxPerimeter.mxPerimeterFunction {

    @Override
    public mxPoint apply(mxRectangle bounds, mxCellState state, mxPoint next, boolean isSource) {

        double x = bounds.getX();
        double y = bounds.getY();
        double w = bounds.getWidth();
        double h = bounds.getHeight();

        double adjustedH = h * 2.0 / 3.0;
        double yOffset = (h - adjustedH) / 2.0;
        double offset = w * 0.2;

        mxPoint p1 = new mxPoint(x + offset,       y + yOffset);
        mxPoint p2 = new mxPoint(x + w,            y + yOffset);
        mxPoint p3 = new mxPoint(x + w - offset,   y + yOffset + adjustedH);
        mxPoint p4 = new mxPoint(x,                y + yOffset + adjustedH);

        mxPoint[] poly = new mxPoint[] { p1, p2, p3, p4 };

        double cx = x + w / 2.0;
        double cy = y + h / 2.0;
        mxPoint center = new mxPoint(cx, cy);

        mxPoint best = null;
        double bestDist = Double.POSITIVE_INFINITY;

        for (int i = 0; i < poly.length; i++) {
            mxPoint a = poly[i];
            mxPoint b = poly[(i + 1) % poly.length];

            mxPoint inter = intersectSegmentWithLine(a, b, center, next);
            if (inter != null) {
                double dx = inter.getX() - next.getX();
                double dy = inter.getY() - next.getY();
                double d2 = dx * dx + dy * dy;
                if (d2 < bestDist) {
                    bestDist = d2;
                    best = inter;
                }
            }
        }

        if (best != null) {
            return best;
        }

        return center;
    }

    private mxPoint intersectSegmentWithLine(mxPoint p1, mxPoint p2, mxPoint q, mxPoint r) {
        double p1x = p1.getX(), p1y = p1.getY();
        double p2x = p2.getX(), p2y = p2.getY();
        double qx = q.getX(), qy = q.getY();
        double rx = r.getX(), ry = r.getY();

        double r_seg_x = p2x - p1x;
        double r_seg_y = p2y - p1y;

        double s_x = rx - qx;
        double s_y = ry - qy;

        double denom = cross(r_seg_x, r_seg_y, s_x, s_y);
        if (Math.abs(denom) < 1e-9) {
            return null;
        }

        double qmpx = qx - p1x;
        double qmpy = qy - p1y;

        double t = cross(qmpx, qmpy, s_x, s_y) / denom;

        if (t >= -1e-9 && t <= 1.0 + 1e-9) {
            double ix = p1x + r_seg_x * t;
            double iy = p1y + r_seg_y * t;
            return new mxPoint(ix, iy);
        }

        return null;
    }

    private double cross(double ax, double ay, double bx, double by) {
        return ax * by - ay * bx;
    }
}