package p5;
import anar.*;




import processing.core.PApplet;

public class Test05bCsplineCurvedPaper extends PApplet {

  /*
   * Example for Anar library by Guillaume LaBelle + Julien Nembrini
   * http://anar.ch
   */


  Obj myObj = new Obj();

  Pt origin = Anar.Pt(0,0,0);

  public void setup(){
    size(800,400,OPENGL);
    Anar.init(this);
    Anar.drawAxis();
    myObj = createModule();
  }

  public Obj createModule(){
    // Initialize a local object
    Obj module = new Obj();

    // First construction: a basic line
    Pts construction = new Pts();

    Param c = new Param(100,0,200);
    Param z = new Param(0);
    Param one = new Param(1);
    
    construction.add(0,0,0);
    construction.add(30,20,0);
    construction.add(60, -20,0);
    construction.add(Anar.Pt(c,z,z));
    construction.add(120,0,40);
    construction.add(150,0,0);
    construction.add(180,0,0);

    // From this first set of points, create a curve of degree 4
    CSpline curve = new CSpline(construction,4);

    Param size = new Param(10,0,50);
    
    // Track parameters of point C
    Anar.sliders(c);
    Anar.sliders(size);

    // Create set of Points from an uniform distribution of points
    Pts curveWithPointsUniform = curve.getPts(200);
    module.add(curveWithPointsUniform);


    // now create a sweep from the darboux vector extracted 
    // from the sequence of points on the curve
    Pts ptsA;
    Pts ptsB;
    Pts ptsC;
    
    // /////////////////////////////
    ptsA = curveWithPointsUniform;
    ptsB = new Pts();
    ptsC = new Pts();
    
    Pts flat = new Pts();
    
    flat.add(origin);
    
    Pt leftOrigin =Anar.Pt(z,size,z);
    Pt rightOrigin =Anar.Pt(z,size.inv(),z);

    Pt leftDir =Anar.Pt(one,size,z);
    Pt rightDir =Anar.Pt(one,size.inv(),z);

    for (int i1 = 1; i1<ptsA.numOfPts()-2; i1++){
        Pt p0 = ptsA.pt(i1-1);
        Pt p1 = ptsA.pt(i1);
        Pt p2 = ptsA.pt(i1+1);
        Pt p3 = ptsA.pt(i1+2);

        PtDarboux omega = new PtDarboux(p0,p1,p2,p3,1);
        
        // find torsion sign : omega_B colinear with T multiplied by torsion
        Param sign = new ParamDot(omega.getOmegaB(),omega.getA().getT0()).sign();
        // TODO sign is zero when curvature is zero ...
        
        Anar.println(sign);
        
        // compute angle between omega and ptsA
        Param angle = new ParamAngle(omega,p1,p2).mul(sign);
        
        
        // report angle on flat paper (keeping the right torsion side of omega)
        // translate to the right point
        flat.add(Anar.Pt(flat.ptEnd().translateX(new ParamLength(p0,p1))));
        Pt dir =  Anar.Pt(1,0,0).rotateZ(angle).translate(flat.ptEnd());
        
        // intersect with borders at distance size on both sides of geodesic ptsA
        PtIntersect inter1 = new PtIntersect(flat.ptEnd(),dir,leftOrigin,leftDir);
        PtIntersect inter2 = new PtIntersect(flat.ptEnd(),dir,rightOrigin,rightDir);
                
        // get parameter for 2 intersections 
        Param l0 = inter1.getLambda();
        Param l1 = inter2.getLambda();
        
        // use distances to generate border points
        ptsB.add(Anar.Pt(omega.getDarboux0()).scale(l0).translate(p1));
        ptsC.add(Anar.Pt(omega.getDarboux0()).scale(l1).translate(p1));
    }
    
    module.add( new SweepTwoPaths(ptsC,ptsB));    
    
    // note: glitches appear in the sweep because the cardinal spline is not C_3 continuous
    
    Anar.camTarget(construction);

    return module;
  }


  public void draw(){
    background(155);
    myObj.draw();
  }


  public void keyPressed(){

    if(key==' ')
      RhinoScript.export(myObj,"curveTest");
  }


  public static void main(String[] args){
    PApplet.main(new String[]{Test05bCsplineCurvedPaper.class.getName()});
  }
}

