Author Topic: Shape script : curved arrow  (Read 4563 times)

bITs.EA

  • EA User
  • **
  • Posts: 80
  • Karma: +2/-0
    • View Profile
Shape script : curved arrow
« 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();
}

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8061
  • Karma: +118/-20
    • View Profile
Re: Shape script : curved arrow
« Reply #1 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();
}

bITs.EA

  • EA User
  • **
  • Posts: 80
  • Karma: +2/-0
    • View Profile
Re: Shape script : curved arrow
« Reply #2 on: April 24, 2014, 07:13:57 pm »
Thanks, it works!

bITs.EA

  • EA User
  • **
  • Posts: 80
  • Karma: +2/-0
    • View Profile
Re: Shape script : curved arrow
« Reply #3 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!!

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8061
  • Karma: +118/-20
    • View Profile
Re: Shape script : curved arrow
« Reply #4 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);
}
« Last Edit: April 28, 2014, 09:41:05 am by simonm »

bITs.EA

  • EA User
  • **
  • Posts: 80
  • Karma: +2/-0
    • View Profile
Re: Shape script : curved arrow
« Reply #5 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);
« Last Edit: April 28, 2014, 07:03:05 pm by bITs.EA »