| /** |
| * Copyright (c) 2006-2015, JGraph Ltd |
| * Copyright (c) 2006-2015, Gaudenz Alder |
| */ |
| var mxPerimeter = |
| { |
| /** |
| * Class: mxPerimeter |
| * |
| * Provides various perimeter functions to be used in a style |
| * as the value of <mxConstants.STYLE_PERIMETER>. Perimeters for |
| * rectangle, circle, rhombus and triangle are available. |
| * |
| * Example: |
| * |
| * (code) |
| * <add as="perimeter">mxPerimeter.RectanglePerimeter</add> |
| * (end) |
| * |
| * Or programmatically: |
| * |
| * (code) |
| * style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter; |
| * (end) |
| * |
| * When adding new perimeter functions, it is recommended to use the |
| * mxPerimeter-namespace as follows: |
| * |
| * (code) |
| * mxPerimeter.CustomPerimeter = function (bounds, vertex, next, orthogonal) |
| * { |
| * var x = 0; // Calculate x-coordinate |
| * var y = 0; // Calculate y-coordainte |
| * |
| * return new mxPoint(x, y); |
| * } |
| * (end) |
| * |
| * The new perimeter should then be registered in the <mxStyleRegistry> as follows: |
| * (code) |
| * mxStyleRegistry.putValue('customPerimeter', mxPerimeter.CustomPerimeter); |
| * (end) |
| * |
| * The custom perimeter above can now be used in a specific vertex as follows: |
| * |
| * (code) |
| * model.setStyle(vertex, 'perimeter=customPerimeter'); |
| * (end) |
| * |
| * Note that the key of the <mxStyleRegistry> entry for the function should |
| * be used in string values, unless <mxGraphView.allowEval> is true, in |
| * which case you can also use mxPerimeter.CustomPerimeter for the value in |
| * the cell style above. |
| * |
| * Or it can be used for all vertices in the graph as follows: |
| * |
| * (code) |
| * var style = graph.getStylesheet().getDefaultVertexStyle(); |
| * style[mxConstants.STYLE_PERIMETER] = mxPerimeter.CustomPerimeter; |
| * (end) |
| * |
| * Note that the object can be used directly when programmatically setting |
| * the value, but the key in the <mxStyleRegistry> should be used when |
| * setting the value via a key, value pair in a cell style. |
| * |
| * The parameters are explained in <RectanglePerimeter>. |
| * |
| * Function: RectanglePerimeter |
| * |
| * Describes a rectangular perimeter for the given bounds. |
| * |
| * Parameters: |
| * |
| * bounds - <mxRectangle> that represents the absolute bounds of the |
| * vertex. |
| * vertex - <mxCellState> that represents the vertex. |
| * next - <mxPoint> that represents the nearest neighbour point on the |
| * given edge. |
| * orthogonal - Boolean that specifies if the orthogonal projection onto |
| * the perimeter should be returned. If this is false then the intersection |
| * of the perimeter and the line between the next and the center point is |
| * returned. |
| */ |
| RectanglePerimeter: function (bounds, vertex, next, orthogonal) |
| { |
| var cx = bounds.getCenterX(); |
| var cy = bounds.getCenterY(); |
| var dx = next.x - cx; |
| var dy = next.y - cy; |
| var alpha = Math.atan2(dy, dx); |
| var p = new mxPoint(0, 0); |
| var pi = Math.PI; |
| var pi2 = Math.PI/2; |
| var beta = pi2 - alpha; |
| var t = Math.atan2(bounds.height, bounds.width); |
| |
| if (alpha < -pi + t || alpha > pi - t) |
| { |
| // Left edge |
| p.x = bounds.x; |
| p.y = cy - bounds.width * Math.tan(alpha) / 2; |
| } |
| else if (alpha < -t) |
| { |
| // Top Edge |
| p.y = bounds.y; |
| p.x = cx - bounds.height * Math.tan(beta) / 2; |
| } |
| else if (alpha < t) |
| { |
| // Right Edge |
| p.x = bounds.x + bounds.width; |
| p.y = cy + bounds.width * Math.tan(alpha) / 2; |
| } |
| else |
| { |
| // Bottom Edge |
| p.y = bounds.y + bounds.height; |
| p.x = cx + bounds.height * Math.tan(beta) / 2; |
| } |
| |
| if (orthogonal) |
| { |
| if (next.x >= bounds.x && |
| next.x <= bounds.x + bounds.width) |
| { |
| p.x = next.x; |
| } |
| else if (next.y >= bounds.y && |
| next.y <= bounds.y + bounds.height) |
| { |
| p.y = next.y; |
| } |
| if (next.x < bounds.x) |
| { |
| p.x = bounds.x; |
| } |
| else if (next.x > bounds.x + bounds.width) |
| { |
| p.x = bounds.x + bounds.width; |
| } |
| if (next.y < bounds.y) |
| { |
| p.y = bounds.y; |
| } |
| else if (next.y > bounds.y + bounds.height) |
| { |
| p.y = bounds.y + bounds.height; |
| } |
| } |
| |
| return p; |
| }, |
| |
| /** |
| * Function: EllipsePerimeter |
| * |
| * Describes an elliptic perimeter. See <RectanglePerimeter> |
| * for a description of the parameters. |
| */ |
| EllipsePerimeter: function (bounds, vertex, next, orthogonal) |
| { |
| var x = bounds.x; |
| var y = bounds.y; |
| var a = bounds.width / 2; |
| var b = bounds.height / 2; |
| var cx = x + a; |
| var cy = y + b; |
| var px = next.x; |
| var py = next.y; |
| |
| // Calculates straight line equation through |
| // point and ellipse center y = d * x + h |
| var dx = parseInt(px - cx); |
| var dy = parseInt(py - cy); |
| |
| if (dx == 0 && dy != 0) |
| { |
| return new mxPoint(cx, cy + b * dy / Math.abs(dy)); |
| } |
| else if (dx == 0 && dy == 0) |
| { |
| return new mxPoint(px, py); |
| } |
| |
| if (orthogonal) |
| { |
| if (py >= y && py <= y + bounds.height) |
| { |
| var ty = py - cy; |
| var tx = Math.sqrt(a*a*(1-(ty*ty)/(b*b))) || 0; |
| |
| if (px <= x) |
| { |
| tx = -tx; |
| } |
| |
| return new mxPoint(cx+tx, py); |
| } |
| |
| if (px >= x && px <= x + bounds.width) |
| { |
| var tx = px - cx; |
| var ty = Math.sqrt(b*b*(1-(tx*tx)/(a*a))) || 0; |
| |
| if (py <= y) |
| { |
| ty = -ty; |
| } |
| |
| return new mxPoint(px, cy+ty); |
| } |
| } |
| |
| // Calculates intersection |
| var d = dy / dx; |
| var h = cy - d * cx; |
| var e = a * a * d * d + b * b; |
| var f = -2 * cx * e; |
| var g = a * a * d * d * cx * cx + |
| b * b * cx * cx - |
| a * a * b * b; |
| var det = Math.sqrt(f * f - 4 * e * g); |
| |
| // Two solutions (perimeter points) |
| var xout1 = (-f + det) / (2 * e); |
| var xout2 = (-f - det) / (2 * e); |
| var yout1 = d * xout1 + h; |
| var yout2 = d * xout2 + h; |
| var dist1 = Math.sqrt(Math.pow((xout1 - px), 2) |
| + Math.pow((yout1 - py), 2)); |
| var dist2 = Math.sqrt(Math.pow((xout2 - px), 2) |
| + Math.pow((yout2 - py), 2)); |
| |
| // Correct solution |
| var xout = 0; |
| var yout = 0; |
| |
| if (dist1 < dist2) |
| { |
| xout = xout1; |
| yout = yout1; |
| } |
| else |
| { |
| xout = xout2; |
| yout = yout2; |
| } |
| |
| return new mxPoint(xout, yout); |
| }, |
| |
| /** |
| * Function: RhombusPerimeter |
| * |
| * Describes a rhombus (aka diamond) perimeter. See <RectanglePerimeter> |
| * for a description of the parameters. |
| */ |
| RhombusPerimeter: function (bounds, vertex, next, orthogonal) |
| { |
| var x = bounds.x; |
| var y = bounds.y; |
| var w = bounds.width; |
| var h = bounds.height; |
| |
| var cx = x + w / 2; |
| var cy = y + h / 2; |
| |
| var px = next.x; |
| var py = next.y; |
| |
| // Special case for intersecting the diamond's corners |
| if (cx == px) |
| { |
| if (cy > py) |
| { |
| return new mxPoint(cx, y); // top |
| } |
| else |
| { |
| return new mxPoint(cx, y + h); // bottom |
| } |
| } |
| else if (cy == py) |
| { |
| if (cx > px) |
| { |
| return new mxPoint(x, cy); // left |
| } |
| else |
| { |
| return new mxPoint(x + w, cy); // right |
| } |
| } |
| |
| var tx = cx; |
| var ty = cy; |
| |
| if (orthogonal) |
| { |
| if (px >= x && px <= x + w) |
| { |
| tx = px; |
| } |
| else if (py >= y && py <= y + h) |
| { |
| ty = py; |
| } |
| } |
| |
| // In which quadrant will the intersection be? |
| // set the slope and offset of the border line accordingly |
| if (px < cx) |
| { |
| if (py < cy) |
| { |
| return mxUtils.intersection(px, py, tx, ty, cx, y, x, cy); |
| } |
| else |
| { |
| return mxUtils.intersection(px, py, tx, ty, cx, y + h, x, cy); |
| } |
| } |
| else if (py < cy) |
| { |
| return mxUtils.intersection(px, py, tx, ty, cx, y, x + w, cy); |
| } |
| else |
| { |
| return mxUtils.intersection(px, py, tx, ty, cx, y + h, x + w, cy); |
| } |
| }, |
| |
| /** |
| * Function: TrianglePerimeter |
| * |
| * Describes a triangle perimeter. See <RectanglePerimeter> |
| * for a description of the parameters. |
| */ |
| TrianglePerimeter: function (bounds, vertex, next, orthogonal) |
| { |
| var direction = (vertex != null) ? |
| vertex.style[mxConstants.STYLE_DIRECTION] : null; |
| var vertical = direction == mxConstants.DIRECTION_NORTH || |
| direction == mxConstants.DIRECTION_SOUTH; |
| |
| var x = bounds.x; |
| var y = bounds.y; |
| var w = bounds.width; |
| var h = bounds.height; |
| |
| var cx = x + w / 2; |
| var cy = y + h / 2; |
| |
| var start = new mxPoint(x, y); |
| var corner = new mxPoint(x + w, cy); |
| var end = new mxPoint(x, y + h); |
| |
| if (direction == mxConstants.DIRECTION_NORTH) |
| { |
| start = end; |
| corner = new mxPoint(cx, y); |
| end = new mxPoint(x + w, y + h); |
| } |
| else if (direction == mxConstants.DIRECTION_SOUTH) |
| { |
| corner = new mxPoint(cx, y + h); |
| end = new mxPoint(x + w, y); |
| } |
| else if (direction == mxConstants.DIRECTION_WEST) |
| { |
| start = new mxPoint(x + w, y); |
| corner = new mxPoint(x, cy); |
| end = new mxPoint(x + w, y + h); |
| } |
| |
| var dx = next.x - cx; |
| var dy = next.y - cy; |
| |
| var alpha = (vertical) ? Math.atan2(dx, dy) : Math.atan2(dy, dx); |
| var t = (vertical) ? Math.atan2(w, h) : Math.atan2(h, w); |
| |
| var base = false; |
| |
| if (direction == mxConstants.DIRECTION_NORTH || |
| direction == mxConstants.DIRECTION_WEST) |
| { |
| base = alpha > -t && alpha < t; |
| } |
| else |
| { |
| base = alpha < -Math.PI + t || alpha > Math.PI - t; |
| } |
| |
| var result = null; |
| |
| if (base) |
| { |
| if (orthogonal && ((vertical && next.x >= start.x && next.x <= end.x) || |
| (!vertical && next.y >= start.y && next.y <= end.y))) |
| { |
| if (vertical) |
| { |
| result = new mxPoint(next.x, start.y); |
| } |
| else |
| { |
| result = new mxPoint(start.x, next.y); |
| } |
| } |
| else |
| { |
| if (direction == mxConstants.DIRECTION_NORTH) |
| { |
| result = new mxPoint(x + w / 2 + h * Math.tan(alpha) / 2, |
| y + h); |
| } |
| else if (direction == mxConstants.DIRECTION_SOUTH) |
| { |
| result = new mxPoint(x + w / 2 - h * Math.tan(alpha) / 2, |
| y); |
| } |
| else if (direction == mxConstants.DIRECTION_WEST) |
| { |
| result = new mxPoint(x + w, y + h / 2 + |
| w * Math.tan(alpha) / 2); |
| } |
| else |
| { |
| result = new mxPoint(x, y + h / 2 - |
| w * Math.tan(alpha) / 2); |
| } |
| } |
| } |
| else |
| { |
| if (orthogonal) |
| { |
| var pt = new mxPoint(cx, cy); |
| |
| if (next.y >= y && next.y <= y + h) |
| { |
| pt.x = (vertical) ? cx : ( |
| (direction == mxConstants.DIRECTION_WEST) ? |
| x + w : x); |
| pt.y = next.y; |
| } |
| else if (next.x >= x && next.x <= x + w) |
| { |
| pt.x = next.x; |
| pt.y = (!vertical) ? cy : ( |
| (direction == mxConstants.DIRECTION_NORTH) ? |
| y + h : y); |
| } |
| |
| // Compute angle |
| dx = next.x - pt.x; |
| dy = next.y - pt.y; |
| |
| cx = pt.x; |
| cy = pt.y; |
| } |
| |
| if ((vertical && next.x <= x + w / 2) || |
| (!vertical && next.y <= y + h / 2)) |
| { |
| result = mxUtils.intersection(next.x, next.y, cx, cy, |
| start.x, start.y, corner.x, corner.y); |
| } |
| else |
| { |
| result = mxUtils.intersection(next.x, next.y, cx, cy, |
| corner.x, corner.y, end.x, end.y); |
| } |
| } |
| |
| if (result == null) |
| { |
| result = new mxPoint(cx, cy); |
| } |
| |
| return result; |
| }, |
| |
| /** |
| * Function: HexagonPerimeter |
| * |
| * Describes a hexagon perimeter. See <RectanglePerimeter> |
| * for a description of the parameters. |
| */ |
| HexagonPerimeter: function (bounds, vertex, next, orthogonal) |
| { |
| var x = bounds.x; |
| var y = bounds.y; |
| var w = bounds.width; |
| var h = bounds.height; |
| |
| var cx = bounds.getCenterX(); |
| var cy = bounds.getCenterY(); |
| var px = next.x; |
| var py = next.y; |
| var dx = px - cx; |
| var dy = py - cy; |
| var alpha = -Math.atan2(dy, dx); |
| var pi = Math.PI; |
| var pi2 = Math.PI / 2; |
| |
| var result = new mxPoint(cx, cy); |
| |
| var direction = (vertex != null) ? mxUtils.getValue( |
| vertex.style, mxConstants.STYLE_DIRECTION, |
| mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; |
| var vertical = direction == mxConstants.DIRECTION_NORTH |
| || direction == mxConstants.DIRECTION_SOUTH; |
| var a = new mxPoint(); |
| var b = new mxPoint(); |
| |
| //Only consider corrects quadrants for the orthogonal case. |
| if ((px < x) && (py < y) || (px < x) && (py > y + h) |
| || (px > x + w) && (py < y) || (px > x + w) && (py > y + h)) |
| { |
| orthogonal = false; |
| } |
| |
| if (orthogonal) |
| { |
| if (vertical) |
| { |
| //Special cases where intersects with hexagon corners |
| if (px == cx) |
| { |
| if (py <= y) |
| { |
| return new mxPoint(cx, y); |
| } |
| else if (py >= y + h) |
| { |
| return new mxPoint(cx, y + h); |
| } |
| } |
| else if (px < x) |
| { |
| if (py == y + h / 4) |
| { |
| return new mxPoint(x, y + h / 4); |
| } |
| else if (py == y + 3 * h / 4) |
| { |
| return new mxPoint(x, y + 3 * h / 4); |
| } |
| } |
| else if (px > x + w) |
| { |
| if (py == y + h / 4) |
| { |
| return new mxPoint(x + w, y + h / 4); |
| } |
| else if (py == y + 3 * h / 4) |
| { |
| return new mxPoint(x + w, y + 3 * h / 4); |
| } |
| } |
| else if (px == x) |
| { |
| if (py < cy) |
| { |
| return new mxPoint(x, y + h / 4); |
| } |
| else if (py > cy) |
| { |
| return new mxPoint(x, y + 3 * h / 4); |
| } |
| } |
| else if (px == x + w) |
| { |
| if (py < cy) |
| { |
| return new mxPoint(x + w, y + h / 4); |
| } |
| else if (py > cy) |
| { |
| return new mxPoint(x + w, y + 3 * h / 4); |
| } |
| } |
| if (py == y) |
| { |
| return new mxPoint(cx, y); |
| } |
| else if (py == y + h) |
| { |
| return new mxPoint(cx, y + h); |
| } |
| |
| if (px < cx) |
| { |
| if ((py > y + h / 4) && (py < y + 3 * h / 4)) |
| { |
| a = new mxPoint(x, y); |
| b = new mxPoint(x, y + h); |
| } |
| else if (py < y + h / 4) |
| { |
| a = new mxPoint(x - Math.floor(0.5 * w), y |
| + Math.floor(0.5 * h)); |
| b = new mxPoint(x + w, y - Math.floor(0.25 * h)); |
| } |
| else if (py > y + 3 * h / 4) |
| { |
| a = new mxPoint(x - Math.floor(0.5 * w), y |
| + Math.floor(0.5 * h)); |
| b = new mxPoint(x + w, y + Math.floor(1.25 * h)); |
| } |
| } |
| else if (px > cx) |
| { |
| if ((py > y + h / 4) && (py < y + 3 * h / 4)) |
| { |
| a = new mxPoint(x + w, y); |
| b = new mxPoint(x + w, y + h); |
| } |
| else if (py < y + h / 4) |
| { |
| a = new mxPoint(x, y - Math.floor(0.25 * h)); |
| b = new mxPoint(x + Math.floor(1.5 * w), y |
| + Math.floor(0.5 * h)); |
| } |
| else if (py > y + 3 * h / 4) |
| { |
| a = new mxPoint(x + Math.floor(1.5 * w), y |
| + Math.floor(0.5 * h)); |
| b = new mxPoint(x, y + Math.floor(1.25 * h)); |
| } |
| } |
| |
| } |
| else |
| { |
| //Special cases where intersects with hexagon corners |
| if (py == cy) |
| { |
| if (px <= x) |
| { |
| return new mxPoint(x, y + h / 2); |
| } |
| else if (px >= x + w) |
| { |
| return new mxPoint(x + w, y + h / 2); |
| } |
| } |
| else if (py < y) |
| { |
| if (px == x + w / 4) |
| { |
| return new mxPoint(x + w / 4, y); |
| } |
| else if (px == x + 3 * w / 4) |
| { |
| return new mxPoint(x + 3 * w / 4, y); |
| } |
| } |
| else if (py > y + h) |
| { |
| if (px == x + w / 4) |
| { |
| return new mxPoint(x + w / 4, y + h); |
| } |
| else if (px == x + 3 * w / 4) |
| { |
| return new mxPoint(x + 3 * w / 4, y + h); |
| } |
| } |
| else if (py == y) |
| { |
| if (px < cx) |
| { |
| return new mxPoint(x + w / 4, y); |
| } |
| else if (px > cx) |
| { |
| return new mxPoint(x + 3 * w / 4, y); |
| } |
| } |
| else if (py == y + h) |
| { |
| if (px < cx) |
| { |
| return new mxPoint(x + w / 4, y + h); |
| } |
| else if (py > cy) |
| { |
| return new mxPoint(x + 3 * w / 4, y + h); |
| } |
| } |
| if (px == x) |
| { |
| return new mxPoint(x, cy); |
| } |
| else if (px == x + w) |
| { |
| return new mxPoint(x + w, cy); |
| } |
| |
| if (py < cy) |
| { |
| if ((px > x + w / 4) && (px < x + 3 * w / 4)) |
| { |
| a = new mxPoint(x, y); |
| b = new mxPoint(x + w, y); |
| } |
| else if (px < x + w / 4) |
| { |
| a = new mxPoint(x - Math.floor(0.25 * w), y + h); |
| b = new mxPoint(x + Math.floor(0.5 * w), y |
| - Math.floor(0.5 * h)); |
| } |
| else if (px > x + 3 * w / 4) |
| { |
| a = new mxPoint(x + Math.floor(0.5 * w), y |
| - Math.floor(0.5 * h)); |
| b = new mxPoint(x + Math.floor(1.25 * w), y + h); |
| } |
| } |
| else if (py > cy) |
| { |
| if ((px > x + w / 4) && (px < x + 3 * w / 4)) |
| { |
| a = new mxPoint(x, y + h); |
| b = new mxPoint(x + w, y + h); |
| } |
| else if (px < x + w / 4) |
| { |
| a = new mxPoint(x - Math.floor(0.25 * w), y); |
| b = new mxPoint(x + Math.floor(0.5 * w), y |
| + Math.floor(1.5 * h)); |
| } |
| else if (px > x + 3 * w / 4) |
| { |
| a = new mxPoint(x + Math.floor(0.5 * w), y |
| + Math.floor(1.5 * h)); |
| b = new mxPoint(x + Math.floor(1.25 * w), y); |
| } |
| } |
| } |
| |
| var tx = cx; |
| var ty = cy; |
| |
| if (px >= x && px <= x + w) |
| { |
| tx = px; |
| |
| if (py < cy) |
| { |
| ty = y + h; |
| } |
| else |
| { |
| ty = y; |
| } |
| } |
| else if (py >= y && py <= y + h) |
| { |
| ty = py; |
| |
| if (px < cx) |
| { |
| tx = x + w; |
| } |
| else |
| { |
| tx = x; |
| } |
| } |
| |
| result = mxUtils.intersection(tx, ty, next.x, next.y, a.x, a.y, b.x, b.y); |
| } |
| else |
| { |
| if (vertical) |
| { |
| var beta = Math.atan2(h / 4, w / 2); |
| |
| //Special cases where intersects with hexagon corners |
| if (alpha == beta) |
| { |
| return new mxPoint(x + w, y + Math.floor(0.25 * h)); |
| } |
| else if (alpha == pi2) |
| { |
| return new mxPoint(x + Math.floor(0.5 * w), y); |
| } |
| else if (alpha == (pi - beta)) |
| { |
| return new mxPoint(x, y + Math.floor(0.25 * h)); |
| } |
| else if (alpha == -beta) |
| { |
| return new mxPoint(x + w, y + Math.floor(0.75 * h)); |
| } |
| else if (alpha == (-pi2)) |
| { |
| return new mxPoint(x + Math.floor(0.5 * w), y + h); |
| } |
| else if (alpha == (-pi + beta)) |
| { |
| return new mxPoint(x, y + Math.floor(0.75 * h)); |
| } |
| |
| if ((alpha < beta) && (alpha > -beta)) |
| { |
| a = new mxPoint(x + w, y); |
| b = new mxPoint(x + w, y + h); |
| } |
| else if ((alpha > beta) && (alpha < pi2)) |
| { |
| a = new mxPoint(x, y - Math.floor(0.25 * h)); |
| b = new mxPoint(x + Math.floor(1.5 * w), y |
| + Math.floor(0.5 * h)); |
| } |
| else if ((alpha > pi2) && (alpha < (pi - beta))) |
| { |
| a = new mxPoint(x - Math.floor(0.5 * w), y |
| + Math.floor(0.5 * h)); |
| b = new mxPoint(x + w, y - Math.floor(0.25 * h)); |
| } |
| else if (((alpha > (pi - beta)) && (alpha <= pi)) |
| || ((alpha < (-pi + beta)) && (alpha >= -pi))) |
| { |
| a = new mxPoint(x, y); |
| b = new mxPoint(x, y + h); |
| } |
| else if ((alpha < -beta) && (alpha > -pi2)) |
| { |
| a = new mxPoint(x + Math.floor(1.5 * w), y |
| + Math.floor(0.5 * h)); |
| b = new mxPoint(x, y + Math.floor(1.25 * h)); |
| } |
| else if ((alpha < -pi2) && (alpha > (-pi + beta))) |
| { |
| a = new mxPoint(x - Math.floor(0.5 * w), y |
| + Math.floor(0.5 * h)); |
| b = new mxPoint(x + w, y + Math.floor(1.25 * h)); |
| } |
| } |
| else |
| { |
| var beta = Math.atan2(h / 2, w / 4); |
| |
| //Special cases where intersects with hexagon corners |
| if (alpha == beta) |
| { |
| return new mxPoint(x + Math.floor(0.75 * w), y); |
| } |
| else if (alpha == (pi - beta)) |
| { |
| return new mxPoint(x + Math.floor(0.25 * w), y); |
| } |
| else if ((alpha == pi) || (alpha == -pi)) |
| { |
| return new mxPoint(x, y + Math.floor(0.5 * h)); |
| } |
| else if (alpha == 0) |
| { |
| return new mxPoint(x + w, y + Math.floor(0.5 * h)); |
| } |
| else if (alpha == -beta) |
| { |
| return new mxPoint(x + Math.floor(0.75 * w), y + h); |
| } |
| else if (alpha == (-pi + beta)) |
| { |
| return new mxPoint(x + Math.floor(0.25 * w), y + h); |
| } |
| |
| if ((alpha > 0) && (alpha < beta)) |
| { |
| a = new mxPoint(x + Math.floor(0.5 * w), y |
| - Math.floor(0.5 * h)); |
| b = new mxPoint(x + Math.floor(1.25 * w), y + h); |
| } |
| else if ((alpha > beta) && (alpha < (pi - beta))) |
| { |
| a = new mxPoint(x, y); |
| b = new mxPoint(x + w, y); |
| } |
| else if ((alpha > (pi - beta)) && (alpha < pi)) |
| { |
| a = new mxPoint(x - Math.floor(0.25 * w), y + h); |
| b = new mxPoint(x + Math.floor(0.5 * w), y |
| - Math.floor(0.5 * h)); |
| } |
| else if ((alpha < 0) && (alpha > -beta)) |
| { |
| a = new mxPoint(x + Math.floor(0.5 * w), y |
| + Math.floor(1.5 * h)); |
| b = new mxPoint(x + Math.floor(1.25 * w), y); |
| } |
| else if ((alpha < -beta) && (alpha > (-pi + beta))) |
| { |
| a = new mxPoint(x, y + h); |
| b = new mxPoint(x + w, y + h); |
| } |
| else if ((alpha < (-pi + beta)) && (alpha > -pi)) |
| { |
| a = new mxPoint(x - Math.floor(0.25 * w), y); |
| b = new mxPoint(x + Math.floor(0.5 * w), y |
| + Math.floor(1.5 * h)); |
| } |
| } |
| |
| result = mxUtils.intersection(cx, cy, next.x, next.y, a.x, a.y, b.x, b.y); |
| } |
| |
| if (result == null) |
| { |
| return new mxPoint(cx, cy); |
| } |
| |
| return result; |
| } |
| }; |