Sparx Systems Forum

Enterprise Architect => Automation Interface, Add-Ins and Tools => Topic started by: bITs.EA on April 24, 2014, 12:42:51 am

Title: Shape script : curved arrow
Post by: bITs.EA on April 24, 2014, 12:42:51 am
Hi

With the following code I can make a curved arrow if I do strokepath (outline are drawn correctly). The problems start when I want to fill this shape: at that point, extra lines are drawn to complete the arc)

Does anybody knows how I can draw a nicely filled curved arrow?

Thanks!

Code: [Select]
shape main{
      noshadow = "true";
      
      setfillcolor(255,0,0);
      
      startpath();
      
      Arc(0, 0, 90, 100, 100, 50, 0, 50);
      moveto(90,50);
      lineto(100,50);
      lineto(83,100);
      lineto(65,50);
      lineto(75,50);
      Arc(15, 15, 75, 75, 75, 50, 15, 50);
      moveto(15,50);
      lineto(0,50);
      
      endpath();
      
      fillandstrokepath();
}
Title: Re: Shape script : curved arrow
Post by: Eve on April 24, 2014, 09:35:11 am
1. Part of the problem is the moveto after the arc. An ArcTo would be better.
2. However, ArcTo aways operates anti-clockwise. You can't do your shape without doing an arc in both directions you will need to drop the arc for the outer loop and approximate using bezierto commands.

You do this using two control points at a ratio of 0.2761423749154 (although most of that precision will be wasted).

That will look like this:
Code: [Select]
shape main{
      noshadow = "true";
      
      setfillcolor(255,0,0);
      
      startpath();
      
      moveto(0,50);
      bezierto(0,12.4,13.8,0,45,0);
      bezierto(77.6,0,90,13.8,90,50);
      lineto(100,50);
      lineto(83,100);
      lineto(65,50);
      lineto(75,50);
//      bezierto(75,24.7,66.7,15,45,15);
//      bezierto(23.3,15,15,24.7,15,50);
      Arcto(15, 15, 75, 75, 75, 50, 15, 50);
      lineto(0,50);
      
      endpath();
      
      fillandstrokepath();
}
Title: Re: Shape script : curved arrow
Post by: bITs.EA on April 24, 2014, 07:13:57 pm
Thanks, it works!
Title: Re: Shape script : curved arrow
Post by: bITs.EA on April 25, 2014, 12:34:47 am
Could you do me one favour, KP?

I want the same arrow, but with the arrow on the left and the curve on the bottom instead of on top. (so arrow will be pointing upwards)

I don't get the bezierto-logic, so I don't manage to make it myself...

Thanks!!
Title: Re: Shape script : curved arrow
Post by: Eve on April 28, 2014, 09:40:28 am
I'm not KP, but I'll update my answer anyway.

Starting with an arc of

      Arc(10, 0, 100, 100, 0, 50, 100, 50)

That needs to be split into two beziers, with 4 points that need to be calculated (a, b, c and d)

      MoveTo(100,50);
        BezierTo(aX, aY, bX, bY, 55, 100);
        BezierTo(cX, cY, dX, dY, 10, 50);

Point a and b are determined by measuring a fraction of 0.27 of the difference from the corner (100,100) to the start and end points.

Point a moves straight up to starting point, the position will be 100- (100-50)*0.27 = 86.5
Point b moves straight across to the target point, the position will be 100-(100-55)*0.27 = 87.8

However, it doesn't look entirely accurate based on the following script that test the approximation. I hope it's accurate enough for your needs because I'm stopping here.

shape main{
      noshadow = "true";
      Arc(10, 0, 100, 100, 0, 50, 100, 50);
      
      SetPenColor(255,0,0);
      MoveTo(100,50);
      BezierTo(100, 86.2, 87.6, 100, 55, 100);
}
Title: Re: Shape script : curved arrow
Post by: bITs.EA on April 28, 2014, 07:02:48 pm
Thanks Simon!

This does the trick!

Code: [Select]
moveto(100,50);
bezierto(100,86.2,87.6,100,55,100);
bezierto(23.8,100,10,87.6,10,50);
lineto(0,50);
lineto(17,0);
lineto(35,50);
lineto(25,50);
Arcto(25, 25, 85, 85, 25, 50, 85, 50);
lineto(100,50);