Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question][libavoid] Help needed for configuring edge routing. #74

Open
haxscramper opened this issue Aug 12, 2024 · 1 comment
Open

Comments

@haxscramper
Copy link

How to force libavoid edges to not overlap with the node body and to have some offset from rectangle nodes?

I have a small graph with several nodes and constraints, and I want to route the edges so they would not cross each other and overlap with the rectangles themselves.

Code from outputInstanceToSVG is under details, generated SVG image is:

adaptagrams_debug

When setting orthogonal routing for edge references and the router itself, I expected something closer to the image below (red lines show preferrable edge positions), but it looks like I'm missing some of the options but cannot figure out which ones exactly.

image

Specifically, I would really appreciate it if someone could point to

  1. Why setRoutingType(Avoid::ConnType::ConnType_Orthogonal) in the Avoid::ConnRef class does not force all edges to consist only of vertical/horizontal lines?
  2. How to force the edges to be attached to the border of the rectangles rather than to the center?
  3. If the edge is attached to the edge of the rectangle, it how to make it have some offset distance from the rectangle so it would not run perfectly parallel? Using ATTACH_POS_BOTTOM for the lower edge moves it around, but it is not clear how to make it have a [-shape.
    image
#include "libavoid/libavoid.h"
using namespace Avoid;
int main(void) {
  Router *router = new Router(PolyLineRouting | OrthogonalRouting);
  router->setRoutingParameter((RoutingParameter)0, 50);
  router->setRoutingParameter((RoutingParameter)1, 0);
  router->setRoutingParameter((RoutingParameter)2, 0);
  router->setRoutingParameter((RoutingParameter)3, 4000);
  router->setRoutingParameter((RoutingParameter)4, 110);
  router->setRoutingParameter((RoutingParameter)5, 0);
  router->setRoutingParameter((RoutingParameter)6, 0);
  router->setRoutingParameter((RoutingParameter)7, 4);
  router->setRoutingParameter((RoutingParameter)8, 0);
  router->setRoutingOption((RoutingOption)0, true);
  router->setRoutingOption((RoutingOption)1, true);
  router->setRoutingOption((RoutingOption)2, false);
  router->setRoutingOption((RoutingOption)3, false);
  router->setRoutingOption((RoutingOption)4, true);
  router->setRoutingOption((RoutingOption)5, false);
  router->setRoutingOption((RoutingOption)6, true);
  Polygon polygon;
  ConnRef *connRef = nullptr;
  ConnEnd srcPt;
  ConnEnd dstPt;
  ConnEnd heConnPt;
  PolyLine newRoute;
  ShapeConnectionPin *connPin = nullptr;

  // shapeRef14
  polygon = Polygon(4);
  polygon.ps[0] = Point(-306.143, -223.138);
  polygon.ps[1] = Point(-206.143, -223.138);
  polygon.ps[2] = Point(-206.143, -323.138);
  polygon.ps[3] = Point(-306.143, -323.138);
  ShapeRef *shapeRef14 = new ShapeRef(router, polygon, 14);
  connPin =
      new ShapeConnectionPin(shapeRef14, 2, 0.5, 0.5, true, 0, (ConnDirFlags)0);

  // shapeRef15
  polygon = Polygon(4);
  polygon.ps[0] = Point(-306.143, 70.7384);
  polygon.ps[1] = Point(-206.143, 70.7384);
  polygon.ps[2] = Point(-206.143, -29.2616);
  polygon.ps[3] = Point(-306.143, -29.2616);
  ShapeRef *shapeRef15 = new ShapeRef(router, polygon, 15);
  connPin =
      new ShapeConnectionPin(shapeRef15, 2, 0.5, 0.5, true, 0, (ConnDirFlags)0);
  connPin =
      new ShapeConnectionPin(shapeRef15, 3, 0.5, 0.5, true, 0, (ConnDirFlags)0);

  // shapeRef16
  polygon = Polygon(4);
  polygon.ps[0] = Point(78.4782, -20.6001);
  polygon.ps[1] = Point(178.478, -20.6001);
  polygon.ps[2] = Point(178.478, -120.6);
  polygon.ps[3] = Point(78.4782, -120.6);
  ShapeRef *shapeRef16 = new ShapeRef(router, polygon, 16);
  connPin =
      new ShapeConnectionPin(shapeRef16, 3, 0.5, 0.5, true, 0, (ConnDirFlags)0);
  connPin =
      new ShapeConnectionPin(shapeRef16, 4, 0.5, 0.5, true, 0, (ConnDirFlags)0);

  // shapeRef17
  polygon = Polygon(4);
  polygon.ps[0] = Point(78.4782, 315.454);
  polygon.ps[1] = Point(178.478, 315.454);
  polygon.ps[2] = Point(178.478, 215.454);
  polygon.ps[3] = Point(78.4782, 215.454);
  ShapeRef *shapeRef17 = new ShapeRef(router, polygon, 17);
  connPin =
      new ShapeConnectionPin(shapeRef17, 4, 0.5, 0.5, true, 0, (ConnDirFlags)0);
  connPin =
      new ShapeConnectionPin(shapeRef17, 5, 0.5, 0.5, true, 0, (ConnDirFlags)0);

  // shapeRef18
  polygon = Polygon(4);
  polygon.ps[0] = Point(-30.856, 315.454);
  polygon.ps[1] = Point(69.144, 315.454);
  polygon.ps[2] = Point(69.144, 215.454);
  polygon.ps[3] = Point(-30.856, 215.454);
  ShapeRef *shapeRef18 = new ShapeRef(router, polygon, 18);
  connPin =
      new ShapeConnectionPin(shapeRef18, 5, 0.5, 0.5, true, 0, (ConnDirFlags)0);
  connPin =
      new ShapeConnectionPin(shapeRef18, 6, 0.5, 0.5, true, 0, (ConnDirFlags)0);

  // shapeRef19
  polygon = Polygon(4);
  polygon.ps[0] = Point(336.413, 315.454);
  polygon.ps[1] = Point(436.413, 315.454);
  polygon.ps[2] = Point(436.413, 215.454);
  polygon.ps[3] = Point(336.413, 215.454);
  ShapeRef *shapeRef19 = new ShapeRef(router, polygon, 19);
  connPin =
      new ShapeConnectionPin(shapeRef19, 6, 0.5, 0.5, true, 0, (ConnDirFlags)0);

  // connRef7
  connRef = new ConnRef(router, 7);
  srcPt = ConnEnd(shapeRef14, 2);
  connRef->setSourceEndpoint(srcPt);
  dstPt = ConnEnd(shapeRef15, 2);
  connRef->setDestEndpoint(dstPt);
  connRef->setRoutingType((ConnType)2);

  // connRef8
  connRef = new ConnRef(router, 8);
  srcPt = ConnEnd(shapeRef15, 3);
  connRef->setSourceEndpoint(srcPt);
  dstPt = ConnEnd(shapeRef16, 3);
  connRef->setDestEndpoint(dstPt);
  connRef->setRoutingType((ConnType)2);

  // connRef9
  connRef = new ConnRef(router, 9);
  srcPt = ConnEnd(shapeRef16, 4);
  connRef->setSourceEndpoint(srcPt);
  dstPt = ConnEnd(shapeRef17, 4);
  connRef->setDestEndpoint(dstPt);
  connRef->setRoutingType((ConnType)2);

  // connRef10
  connRef = new ConnRef(router, 10);
  srcPt = ConnEnd(shapeRef17, 5);
  connRef->setSourceEndpoint(srcPt);
  dstPt = ConnEnd(shapeRef18, 5);
  connRef->setDestEndpoint(dstPt);
  connRef->setRoutingType((ConnType)2);

  // connRef11
  connRef = new ConnRef(router, 11);
  srcPt = ConnEnd(shapeRef18, 6);
  connRef->setSourceEndpoint(srcPt);
  dstPt = ConnEnd(shapeRef19, 6);
  connRef->setDestEndpoint(dstPt);
  connRef->setRoutingType((ConnType)2);

  router->processTransaction();
  router->outputInstanceToSVG("orthogonalOpt2");
  delete router;
  return 0;
};
@Aksem
Copy link

Aksem commented Nov 17, 2024

In shape connection pin intsantiation you have new ShapeConnectionPin(shapeRef14, 2, 0.5, 0.5, true, 0, (ConnDirFlags)0);
third and fourth values are X and Y position of your pin. And fifth means relative or absolute. 0.5, 0.5, true, means relative position 0.5 of shape width from left, 0.5 of shape height from the top.

One possible solution would be to create a pin on each side of shape with positions (0.5, 0, true), (1, 0.5, true), (0.5, 1, true), (0, 0.5, true). Or if shape sides, where pins should be, are known in advance, keep only those pins.

Feel free to ask further questions in my actively maintained fork of adaptagrams: https://github.com/Aksem/adaptagrams/issues even if you use original adaptagrams version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants