Tutorials | (back to the list of tutorials) |
Similarly, a NURBS surface is defined by the formula below, where now control points Pi,j and weights wi,j are provided as n x m matrix. This is a function of two parameters u and v and it returns spatial coordinates corresponding to the input u and v.
For more detail description of NURBS geometries and basis functions, see Wikipedia pages of NURBS, B-Spline and Bernstein Polynomial
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec[] controlPoints1 = new IVec[4]; controlPoints1[0] = new IVec(0, 0, 0); controlPoints1[1] = new IVec(20, 30, 30); controlPoints1[2] = new IVec(40, -30, -30); controlPoints1[3] = new IVec(60, 0, 0); int deg1 = 3; new ICurve(controlPoints1, deg1).clr(0); IVec4[] controlPoints2 = new IVec4[4]; controlPoints2[0] = new IVec4(0, 0, 0, 1); controlPoints2[1] = new IVec4(20, 30, 30, 0.5); controlPoints2[2] = new IVec4(40, -30, -30, 0.5); controlPoints2[3] = new IVec4(60, 0, 0, 1); int deg2 = 3; new ICurve(controlPoints2, deg2).clr(1.,0,0); IVec[][] controlPoints3 = new IVec[][]{ new IVec[]{ new IVec(-70,0,0), new IVec(-70,20,30), new IVec(-70,40,0) }, new IVec[]{ new IVec(-50,30,30), new IVec(-50,50,60), new IVec(-50,70,30) }, new IVec[]{ new IVec(-30,-30,-30), new IVec(-30,-10,0), new IVec(-30,10,-30) }, new IVec[]{ new IVec(-10,0,30), new IVec(-10,20,60), new IVec(-10,40,30) } }; int udeg3 = 3, vdeg3 = 2; new ISurface(controlPoints3, udeg3, vdeg3).clr(0); IVec4[][] controlPoints4 = new IVec4[][]{ new IVec4[]{ new IVec4(-70,0,0,1), new IVec4(-70,20,30,.5), new IVec4(-70,40,0,1) }, new IVec4[]{ new IVec4(-50,30,30,.5), new IVec4(-50,50,60,.5), new IVec4(-50,70,30,.5) }, new IVec4[]{ new IVec4(-30,-30,-30,.5), new IVec4(-30,-10,0,.5), new IVec4(-30,10,-30,.5) }, new IVec4[]{ new IVec4(-10,0,30,1), new IVec4(-10,20,60,.5), new IVec4(-10,40,30,1) } }; int udeg4 = 3, vdeg4 = 2; new ISurface(controlPoints4, udeg4, vdeg4).clr(1,.5,1);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec curveEdgePt = new IVec(10,0,0); IVec curveTangent = new IVec(20,20,20); IVec[] cpts1 = new IVec[3]; cpts1[0] = curveEdgePt; cpts1[1] = curveEdgePt.dup().sub(curveTangent); cpts1[2] = new IVec(0, 40, -40); IVec[] cpts2 = new IVec[4]; cpts2[0] = curveEdgePt; cpts2[1] = curveEdgePt.dup().add(curveTangent); cpts2[2] = new IVec(60,0,0); cpts2[3] = new IVec(100,0,0); new ICurve(cpts1, 2).clr(1.,0,0); new ICurve(cpts2, 3).clr(.5,0,1); // showing control points for(int i=0; i < cpts1.length; i++){ new IPoint(cpts1[i]).clr(1.,0,0); } for(int i=0; i < cpts2.length; i++){ new IPoint(cpts2[i]).clr(.5,0,1); } // showing straight relationship new ICurve(cpts1[1], cpts2[1]);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec surfaceTangent1 = new IVec(20, 0, -10); IVec surfaceTangent2 = new IVec(20, -20, -10); IVec surfaceEdgePt1 = new IVec(0, 0, 0); IVec surfaceEdgePt2 = new IVec(0, 30, 0); IVec[][] cpts3 = new IVec[3][2]; cpts3[0][0] = surfaceEdgePt1; cpts3[0][1] = surfaceEdgePt2; cpts3[1][0] = surfaceEdgePt1.dup().sub(surfaceTangent1); cpts3[1][1] = surfaceEdgePt2.dup().sub(surfaceTangent2); cpts3[2][0] = new IVec(-10, 0, -30); cpts3[2][1] = new IVec(-10, 30, -30); IVec[][] cpts4 = new IVec[3][2]; cpts4[0][0] = surfaceEdgePt1; cpts4[0][1] = surfaceEdgePt2; cpts4[1][0] = surfaceEdgePt1.dup().add(surfaceTangent1); cpts4[1][1] = surfaceEdgePt2.dup().add(surfaceTangent2); cpts4[2][0] = new IVec(10, 0, 30); cpts4[2][1] = new IVec(10, 30, 30); new ISurface(cpts3, 2, 1).clr(0,0,1.); new ISurface(cpts4, 2, 1).clr(0,.5,1.); // showing control points for(int i=0; i < cpts3.length; i++){ for(int j=0; j< cpts3[i].length; j++){ new IPoint(cpts3[i][j]).clr(0,0,1.); } } for(int i=0; i < cpts4.length; i++){ for(int j=0; j< cpts4[i].length; j++){ new IPoint(cpts4[i][j]).clr(0,.5,1.); } } // showing straight relationship new ICurve(cpts3[1][0], cpts4[1][0]); new ICurve(cpts3[1][1], cpts4[1][1]);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec[] cpts=new IVec[]{new IVec(-60,0,0),new IVec(-20,0,0), new IVec(20,0,60),new IVec(60,0,-30)}; ICurve curve = new ICurve(cpts, 2); IVec pt1 = curve.pt(0.5); IVec pt2 = curve.pt(0.8); IVec pt3 = curve.pt(1.0); // showing points new IPoint(pt1).clr(1.,0,0); new IPoint(pt2).clr(1.,.5,0); new IPoint(pt3).clr(0,.5,0); // using them for creating other geometries new ICurve(new IVec(0,60,-20), pt1).clr(1.,0,0); new ICurve(new IVec(0,60,-20), pt2).clr(1.,.5,0); new ICurve(new IVec(0,60,-20), pt3).clr(0,.5,0);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec[] cpts=new IVec[]{new IVec(-30,10,0),new IVec(-10,0,0), new IVec(10,0,30),new IVec(30,0,-10)}; ICurve curve = new ICurve(cpts, 2); IVec tan1 = curve.tan(0); IVec tan2 = curve.tan(0.5); IVec tan3 = curve.tan(0.8); IVec tan4 = curve.tan(1.0); // showing arrows at each point on the curve tan1.show(curve.pt(0)).clr(1.,1.,0).size(10); tan2.show(curve.pt(0.5)).clr(1.,0,0).size(10); tan3.show(curve.pt(0.8)).clr(1,.5,0).size(10); tan4.show(curve.pt(1.0)).clr(0,.5,0).size(10);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec[][] cpts = new IVec[][]{ new IVec[]{ new IVec(-40,-20,-20), new IVec(0,0,0), new IVec(40,0,-20) }, new IVec[]{ new IVec(-40,30,20), new IVec(0,30,0), new IVec(40,30,-10) } }; ISurface surface = new ISurface(cpts,1,2); IVec pt1 = surface.pt(0.5,0.5); IVec pt2 = surface.pt(0.5,1.0); IVec pt3 = surface.pt(0.3,0.2); // showing points new IPoint(pt1).clr(1.,0,0); new IPoint(pt2).clr(1,.5,0); new IPoint(pt3).clr(0,.5,0); // using them for creating other geometries new ICurve(new IVec(-20,0,40), pt1).clr(1.,0,0); new ICurve(new IVec(-20,0,40), pt2).clr(1,.5,0); new ICurve(new IVec(-20,0,40), pt3).clr(0,.5,0);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec[][] cpts = new IVec[][]{ new IVec[]{ new IVec(-40,-20,-20), new IVec(0,0,0), new IVec(40,0,-20) }, new IVec[]{ new IVec(-40,30,20), new IVec(0,30,0), new IVec(40,30,-10) } }; ISurface surface = new ISurface(cpts,1,2); IVec utan1 = surface.utan(0.5,0.5); IVec utan2 = surface.utan(0.5,1.0); IVec vtan1 = surface.vtan(0.5,0.5); IVec vtan2 = surface.vtan(0.5,1.0); // showing arrows at each point on the surface utan1.show(surface.pt(0.5,0.5)).clr(1.,0,0).size(5); utan2.show(surface.pt(0.5,1.0)).clr(0,0,1.).size(5); vtan1.show(surface.pt(0.5,0.5)).clr(1,.5,0).size(5); vtan2.show(surface.pt(0.5,1.0)).clr(0,.5,1).size(5);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec[][] cpts = new IVec[][]{ new IVec[]{ new IVec(-40,30,20), new IVec(0,30,0), new IVec(40,30,-10) }, new IVec[]{ new IVec(-40,-20,-20), new IVec(0,0,0), new IVec(40,0,-20) } }; ISurface surface = new ISurface(cpts,1,2); IVec normal1 = surface.nrml(0.5,0.5).len(40); IVec normal2 = surface.nrml(1.0,0.5).len(40); IVec normal3 = surface.nrml(0.0,0.5).len(40); IVec normal4 = surface.nrml(0.2,0.8).len(40); // showing arrows at each point on the surface normal1.show(surface.pt(0.5,0.5)).clr(1.,0,0).size(10); normal2.show(surface.pt(1.0,0.5)).clr(1.,.5,0).size(10); normal3.show(surface.pt(0.0,0.5)).clr(0,.5,0).size(10); normal4.show(surface.pt(0.2,0.8)).clr(0,.5,1).size(10);
import processing.opengl.*; import igeo.*; size( 480, 360, IG.GL ); IVec[][] cpts = new IVec[][]{ new IVec[]{ new IVec(-40,30,20), new IVec(0,30,0), new IVec(40,30,-10) }, new IVec[]{ new IVec(-40,-20,-20), new IVec(0,0,0), new IVec(40,0,-20) } }; ISurface surface = new ISurface(cpts,1,2); IVec pt1 = surface.pt(0.5, 0.5, 10); IVec pt2 = surface.pt(0.8, 0.5, 10); IVec pt3 = surface.pt(0.8, 0.8, 10); IVec pt4 = surface.pt(0.5, 0.8, 10); // showing points new IPoint(pt1).clr(1.,0,0); new IPoint(pt2).clr(1.,.5,0); new IPoint(pt3).clr(0,.5,0); new IPoint(pt4).clr(0,.5,1); // using them for creating other geometries new ISurface(pt1,pt2,pt3,pt4).clr(.5,0,1);