PIPRIME.FR BLOG

Live fully to honor life

Category Path Orientation -- Asymptote Gallery

đź”—ccw-fig001

Figure ccw 001 Generated with Asymptote

Usage of the algorithm "Simple Polygon Orientation".

Show ccw/fig0010.asy on Github.
Generated with Asymptote 3.00-0.
Categories : Surveys | Path Orientation

size(8cm, false);

real signedArea(pair [] pt)
{
  // Return the signed area of a simple (NON CROSSED) polygon of vertex "pt"
  // Retourne l'aire algébrique d'un polygone NON CROISÉ
  pair [] pt_= copy(pt);
  real n=pt.length,
    sa=0;
  pt_.push(pt_[0]);
  pt_.push(pt_[1]);

  for (int i=1; i<=n; ++i) sa +=pt_[i].x * (pt_[i+1].y - pt_[i-1].y);
  return sa/2;
}

bool counterclockwise(pair [] pt)
{
  // Return "true" if the polygon (SIMPLE CURVE i.e. NON CROSSED)
  // of vertex "pt" is counterclockwise
  // Retourne "true" si le polygone (NON CROISÉ) de sommets "pt"
  // est dans le sens des aiguilles d'une montre
  return (signedArea(pt) > 0);
}

pair [] reverse(pair [] pt)
{
  pair [] pt_=copy(pt);
  int begin=0, end=pt.length-1;
  while (begin<end)
    {
      pair temp=pt_[begin];
      pt_[begin]=pt_[end];
      pt_[end]=temp;
      ++begin; --end;
    }
  return pt_;
}

pair [] counterclockdirected(pair [] pt)
{
  if (counterclockwise(pt)) return pt; else return reverse(pt);
}

path polygon(pair [] pt)
{
  int l=pt.length;
  guide opath;
  for (int i=0; i<l; ++i)
    {
      opath = opath--pt[i];
    }
  return opath;
}

pair [] pg = {(0,0), (1,0), (1,1), (2,2), (-1,1)};
draw(polygon(pg)--cycle,
     Arrow(Relative(.1)), BeginBar);
draw(polygon(counterclockdirected(reverse(pg)))--cycle,
     Arrow(position=Relative(.2), FillDraw(red)), BeginBar);

đź”—ccw-fig002

Figure ccw 002 Generated with Asymptote

Show ccw/fig0020.asy on Github.
Generated with Asymptote 3.00-0.
Categories : Surveys | Path Orientation

size(6cm);
bool counterclockwise(path g, int n=10^3)
{
  // Return "true" if "g" (SIMPLE CURVE i.e. NON CROSSED) is counterclockwise
  // Retounre "true" si "g" (NON CROISÉ) est dans le sens contraire des aiguilles d'une montre
  if (!cyclic(g) || length(g)==0) abort("The function 'clocksize' needs cyclic path.");
  pair [] pt;
  real l=length(g),
    step=1/n,
    t=0,
    sa=0;
  do {
    sa +=point(g,t).x * (point(g,t+step).y - point(g,t-step).y);
    t+=step;
  } while (t<l);
  return (sgn(sa) > 0);
}

path counterclockdirected(path g,int n=10^3)
{
  // Return "g" (SIMPLE CURVE i.e. NON CROSSED) counterclockwise
  // Retourne "g" (NON CROISÉ) dans le sens des aiguilles d'une montre
  if (counterclockwise(g,n)) return g; else return reverse(g);
}

path p=unitcircle;
draw(counterclockdirected(reverse(p)),
     Arrow(Relative(.1)), BeginBar);
draw(counterclockdirected(p),
     Arrow(position=Relative(.2),FillDraw(red)), BeginBar);

đź”—ccw-fig003

Figure ccw 003 Generated with Asymptote

Use of the native windingnumber Asymptote routine this is the most fast and robust.

Utilisation du nombre d'enroulement avec la routine native windingnumber d'Asymptote c'est plus rapide et plus robuste.

Explanations are here.

Show ccw/fig0030.asy on Github.
Generated with Asymptote 3.00-0.
Categories : Surveys | Path Orientation

size(6cm,0, false);
bool counterclockwise(path g, pair z) {return windingnumber(g,z) > 0;}

path counterclockdirected(path g,pair z)
{
  if (counterclockwise(g,z)) return g; else return reverse(g);
}

pair z=(1,0);
dot(z);
path p=(0,0){N}..(4,0){N}..cycle;
draw(counterclockdirected(reverse(p),z),Arrow(Relative(.1)), BeginBar);
draw(counterclockdirected(p,z),Arrow(position=Relative(.2),FillDraw(red)), BeginBar);

pair z=(3,-2);
dot(z);
path p=(4,-2){N}..(0,-2){N}..cycle;
draw(counterclockdirected(reverse(p),z),Arrow(Relative(.1)), BeginBar);
draw(counterclockdirected(p,z),Arrow(position=Relative(.2),FillDraw(red)), BeginBar);

pair z=(1,-4.5);
dot(z);
path p=yscale(.75)*((0,-6){N}..(2,-6){S}..(0,-6){N}..(4,-6){S}..cycle);
draw(counterclockdirected(reverse(p),z),Arrow(Relative(.1)), BeginBar);
draw(counterclockdirected(p,z),Arrow(position=Relative(.2),FillDraw(red)), BeginBar);

pair z=(3,-8);
dot(z);
path p=shift((0,-3.5))*p;
draw(counterclockdirected(reverse(p),z),Arrow(Relative(.1)), BeginBar);
draw(counterclockdirected(p,z),Arrow(position=Relative(.2),FillDraw(red)), BeginBar);

đź”—ccw-fig004

Figure ccw 004 Generated with Asymptote

Show ccw/fig0040.asy on Github.
Generated with Asymptote 3.00-0.
Categories : Surveys | Path Orientation

// Use of the windingnumber works also for CROSSED curves

size(8cm,10cm,false);

import math;

bool counterclockwise(path g)
{
  // Return "true" if "g" is counterclockwise
  // Retounre "true" si "g" est dans le sens contraire des aiguilles d'une montre
  return (windingnumber(g,inside(g)) > 0);
}

path counterclockdirected(path g)
{
  if (counterclockwise(g)) return g; else return reverse(g);
}

guide p=randompath(30)..cycle;
draw(counterclockdirected(reverse(p)),Arrow(10bp,Relative(0.025)), BeginBar);
draw(counterclockdirected(p),Arrow(10bp,FillDraw(red),Relative(.05)), BeginBar);

0%