Post Reply 
Bézier Curves (Bezier curves)
01-16-2018, 10:08 PM
Post: #2
RE: Bezier Curves
Bezier curves V0.1 allows the points on a Bezier curve to be generated and drawn.

Code:


 LOCAL CRID:="Bézier V0.1 StephenG1CMZ 2018";

 //LOCAL ImpSTEPSZ:=1/(10000-2);//Most Detailed-List Limit
 //! Android: Insufficient Memory may occur. 
 //These steps allow a spline along a diagonal
 //LOCAL GSTEPSZ:=1/(4406-2); //4K
 //LOCAL GSTEPSZ:=1/(2203-2); //HD
 //LOCAL GSTEPSZ:=1/(800-2);//VGA
 EXPORT GSTEPSZ:=1/(400-2);//QVGA
 //0..1 ALSO IMP>0.001=10000 PTS
 EXPORT ROTMATRIX:=[[1,0],[0,1]];//DEFAULT: NO ROT (ONLY USED WITH CN=1)
 LOCAL CN:=1;//0=POINTS 1=LINES (EXAMPLES)
 
 //NB PROCEDURES RETURN COMPLEX REAL (X,Y) VALUES
 //WHICH YOU MIGHT WISH TO PIXELLATE 
 //PROCEDURES PREFIXED G GENERATE CURVE POINTS
 //PROCEDURES SUFFIXED 1 GENERATE 1 POINT
 //POLYBEZIER NOT IMLEMENTED:ADDITIONAL PARAMETERS IGNORED
 GETPT(N1,N2,PERCY)
 //FRACTION ALONG LINE:X OR Y
 //USED BY BEZIER PROCS
 BEGIN
  LOCAL DFF:=N2-N1;
  RETURN (N1+(DFF*PERCY)); 
  //
 END;

 EXPORT GBezierQUAD1 (XX,YY,PERCY)
 //Generate a point along a Bezier Quadratic curve
 //PERCY AND II: 0..1
 BEGIN
  LOCAL XA,YA,XB,YB;
  LOCAL II:=PERCY; 
   
   // FIRST CONSTRUCT GREEN LINE
   XA:=GETPT(XX(1),XX(2),II);
   YA:=GETPT(YY(1),YY(2),II);
   XB:=GETPT(XX(2),XX(3),II);
   YB:=GETPT(YY(2),YY(3),II);
   //GENERATE BEZIER POINT
   RETURN ((GETPT(XA,XB,II)),(GETPT(YA,YB,II))); 
 END;

 EXPORT GBezierQUAD(XX,YY)
 //Generate Bezier Quadratic curve
 //XY: 1 AND 3 ON CURVE. 2 CONTROLPT.
 BEGIN
  LOCAL II;
  LOCAL XA,YA,XB,YB;
  LOCAL PTS:={};
  //FOR EACH
  FOR II FROM 0 TO 1 STEP GSTEPSZ DO
   PTS(0):=GBezierQUAD1(XX,YY,II);
  END;//FOR
  //ENSURE PT3 ON CURVE
  PTS(0):=GBezierQUAD1(XX,YY,1); //(XX(3),YY(3));
  RETURN PTS;
 END;

 EXPORT GBezierCUBIC1(XX,YY,PERCY)
 //Generate a point along a Bezier Cubic curve
 //PERCY AND II: 0..1
 BEGIN
  LOCAL II:=PERCY;
  LOCAL XA,YA,XB,YB,XC,YC;
  LOCAL XM,YM,XN,YN;

   // FIRST CONSTRUCT GREEN LINES
   XA:=GETPT(XX(1),XX(2),II);
   YA:=GETPT(YY(1),YY(2),II);
   XB:=GETPT(XX(2),XX(3),II);
   YB:=GETPT(YY(2),YY(3),II);
   XC:=GETPT(XX(3),XX(4),II);
   YC:=GETPT(YY(3),YY(4),II);
   //BLUE LINE
   XM:=GETPT(XA,XB,II);
   YM:=GETPT(YA,YB,II);
   XN:=GETPT(XB,XC,II);
   YN:=GETPT(YB,YC,II);

   //GENERATE BEZIER POINT
   RETURN (GETPT(XM,XN,II),GETPT(YM,YN,II));//X AND Y
 END;

 EXPORT GBezierCUBIC(XX,YY)
 //Generate Bezier Cubic curve
 //XY: 1 AND 4 ON CURVE. 2 AND 3 CONTROL PT.
 BEGIN
  LOCAL II;
  LOCAL PTS:={};

  //FOR EACH
  FOR II FROM 0 TO 1 STEP GSTEPSZ DO
   PTS(0):=GBezierCUBIC1(XX,YY,II); //X AND Y
  END;//FOR
  //ENSURE PT4 ON CURVE
  PTS(0):=GBezierCUBIC1(XX,YY,1); //(XX(4),YY(4));
  RETURN PTS;
 END;

 EXPORT DRAWC(PTS,COLR,CONN)
 //DRAW POINTS CONNECTED
 //PTS: (X,Y) AS COMPLEX ie LINE FORMT
 //CONN 0: POINTS 1 BY 1 
 //CONN 1: LINES ALL AT ONCE
 //(GUARDS AGANST GAPS)
 //TBD: IMPLEMENT _P AND NON_P VARIANTS
 BEGIN
  LOCAL II;
  LOCAL LINESLST:={};

  CASE
   IF SIZE(PTS)==0 THEN //NOTHING TO DRAW
   END;
   IF CONN==0 OR SIZE(PTS)==1 THEN //POINTS
    FOR II FROM 1 TO SIZE(PTS)  DO
      PIXON_P(RE(PTS(II)),IM(PTS(II)),COLR);
      //WAIT(1);//ANIMABLE
    END;  
   END; //POINTS
   IF CONN==1  THEN //LINES
     LINESLST:=MAKELIST({II-1,II},II,2,SIZE(PTS));
     LINE_P(PTS,CONCAT(COLR,LINESLST),ROTMATRIX);
     //LINE_P(G9,PTS,CONCAT(COLR,LINESLST),ROTMATRIX);
     
   END; //LINES
   DEFAULT
   //UNKNOWN CONN
  END;//CASE
 END;

 EXPORT IsOnCurve(Points,Point,Rounding)
 //Is PT on curve described by PTS
 //Points:Points comprising curve
 //Point: Search Point (Complex XY)
 //Rounding: −12..12 allows inexact real matches 
 //NB if points change, conclusion may
 //Enhancements: Consider alternatives to rounding
 BEGIN
  LOCAL RND:=Rounding;
  RETURN POS(ROUND(Points,RND),ROUND(Point,RND));
 END;

 EXPORT BezierExample()
 BEGIN
 LOCAL TM,GTIME;
 LOCAL PTS;
 LOCAL COLR:=#FF00FF;
 LOCAL GSTEPSZ_SAVE:=GSTEPSZ;
 GSTEPSZ:=1/(200-2);//LOCALVALUE FOR DEMO
 
 RECT_P();
 TEXTOUT_P(CRID,0,220);
 TEXTOUT_P("Generate",0,0);
 DRAWC({(320/2,240/2)},COLR,CN);//TEST 1 PT
 DRAWC({},COLR,CN);//TEST NULL
 TEXTOUT_P("Draw",160,0);
 TEXTOUT_P(TEVAL(PTS:=GBezierQUAD({10,80,240},{200,100,150})),0,20);
 TEXTOUT_P(TEVAL(DRAWC(PTS,COLR,CN)),160,20);
 TEXTOUT_P(SIZE(PTS)+" Points/Bézier",0,200);
 TEXTOUT_P(TEVAL(PTS:=GBezierCUBIC({10,0,150,240},{200,20,20,150})),0,40);
 TEXTOUT_P(TEVAL(DRAWC(PTS,COLR,CN)),160,40);
 TEXTOUT_P(TEVAL(PTS:=GBezierQUAD({100,250,250,325},{100,100,200,350})),0,60​);
 TEXTOUT_P(TEVAL(DRAWC(PTS,#FF0000,CN)),160,60);
 GSTEPSZ:=GSTEPSZ_SAVE;
 //PRINT();
 //PRINT("RESULT:POS is "+IsOnCurve({(1,2)},(1,2),0));
 WAIT;
 END;

 EXPORT BEZIER()
 BEGIN
  BezierExample();
 END;

Quadratic Bezier and Cubic Bezier are implemented, but Polybeziers are not yet implemented.

Stephen Lewkowicz (G1CMZ)
https://my.numworks.com/python/steveg1cmz
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: Bezier Curves - StephenG1CMZ - 01-16-2018 10:08 PM



User(s) browsing this thread: 1 Guest(s)