private void chooseRouteOutlinePoints(Link orgnLink, Link destLink, ref PointF ptOrg, ref PointF ptDest) { RoutingOptions rop = flowChart.RoutingOptions; Node origin = orgnLink.getNode(); Node destination = destLink.getNode(); bool reflexive = orgnLink.sameNode(destLink); // how many points to consider ? int srcCount = rop.StartOrientation == Orientation.Auto ? 4 : 2; int dstCount = rop.EndOrientation == Orientation.Auto ? 4 : 2; PointF[] srcPoints = new PointF[srcCount]; PointF[] dstPoints = new PointF[dstCount]; // determine the coordinates of the points to be checked ... int srcIdx = 0, dstIdx = 0; // source points if (rop.StartOrientation != Orientation.Vertical) { srcPoints[srcIdx++] = orgnLink.getIntersection(ptOrg, new PointF(ptOrg.X - 2*origin.BoundingRect.Width, ptOrg.Y)); srcPoints[srcIdx++] = orgnLink.getIntersection(ptOrg, new PointF(ptOrg.X + 2*origin.BoundingRect.Width, ptOrg.Y)); } if (rop.StartOrientation != Orientation.Horizontal) { srcPoints[srcIdx++] = orgnLink.getIntersection(ptOrg, new PointF(ptOrg.X, ptOrg.Y - 2*origin.BoundingRect.Height)); srcPoints[srcIdx++] = orgnLink.getIntersection(ptOrg, new PointF(ptOrg.X, ptOrg.Y + 2*origin.BoundingRect.Height)); } // destination points if (rop.EndOrientation != Orientation.Vertical) { dstPoints[dstIdx++] = dstPoints[1] = destLink.getIntersection(ptDest, new PointF(ptDest.X - 2*destination.BoundingRect.Width, ptDest.Y)); dstPoints[dstIdx++] = destLink.getIntersection(ptDest, new PointF(ptDest.X + 2*destination.BoundingRect.Width, ptDest.Y)); } if (rop.EndOrientation != Orientation.Horizontal) { dstPoints[dstIdx++] = destLink.getIntersection(ptDest, new PointF(ptDest.X, ptDest.Y - 2*destination.BoundingRect.Height)); dstPoints[dstIdx++] = destLink.getIntersection(ptDest, new PointF(ptDest.X, ptDest.Y + 2*destination.BoundingRect.Height)); } // check which of these points are closest ptOrg = srcPoints[0]; ptDest = dstPoints[0]; float minDist = Single.MaxValue; for (int sidx = 0; sidx < srcCount; ++sidx) { if (!reflexive && destination.containsPoint(srcPoints[sidx])) continue; for (int didx = 0; didx < dstCount; ++didx) { if (!reflexive && origin.containsPoint(dstPoints[didx])) continue; float dist = Utilities.Distance( srcPoints[sidx], dstPoints[didx]); if (dist < 2 * rop.GridSize) continue; // we prefer these to be on the same side if (sidx != didx) dist *= 3; if (dist < minDist) { minDist = dist; ptOrg = srcPoints[sidx]; ptDest = dstPoints[didx]; } } } }
private void setEndPoints(Link orgnLink, Link destLink, PointF end) { reflexive = destLink.sameNode(orgnLink); // align the end points of the arrow to the outlines of the connected nodes if (orgnLink.calcIntrs()) ptOrg = points[0] = orgnLink.getInitialPt(); if (destLink.calcIntrs()) ptEnd = destLink.getInitialPt(); else ptEnd = end; if (!orgnLink.objsIntersect(destLink) && !reflexive) { if (orgnLink.calcIntrs()) ptOrg = points[0] = orgnLink.getIntersection(ptOrg, ptEnd); if (destLink.calcIntrs()) ptEnd = destLink.getIntersection(ptEnd, ptOrg); } else { // if the arrow will be routed, choose the closest points on the // horizontal line intersections with the node outlines. These points // should not be contained within a node if (autoRoute && !dynamic && orgnAnchor == -1 && destAnchor == -1) { chooseRouteOutlinePoints(orgnLink, destLink, ref ptOrg, ref ptEnd); points[0] = ptOrg; } } }
internal void setOrgAndDest(Link orgLink, Link trgLink) { orgnLink = orgLink; destLink = trgLink; // place the end points of the arrow at their respective object edge points[0] = orgnLink.getInitialPt(); points[points.Count-1] = destLink.getInitialPt(); if (!orgnLink.objsIntersect(destLink)) { points[0] = orgnLink.getIntersection(points[0], points[points.Count-1]); points[points.Count-1] = destLink.getIntersection(points[points.Count-1], points[0]); } points[0] = orgnLink.getAnchor(points[0], this, false, ref orgnAnchor); points[points.Count-1] = destLink.getAnchor(points[points.Count-1], this, true, ref destAnchor); // set reflexive arrow position & form reflexive = orgnLink.sameNode(destLink); if (reflexive) { setReflexive(); } else { // compute the arrow points updatePoints(points[points.Count-1]); if (dynamic) updatePosFromOrgAndDest(true); } rectFromPoints(); // relative position to nodes orgnLink.saveEndRelative(); destLink.saveEndRelative(); doRoute(); }