0% found this document useful (0 votes)
717 views

Bezier-Surfaces C++ Code

The document contains C++ code for calculating intermediate points and derivatives for 3D Bezier curves and surfaces. It includes classes for 3D vectors, Bezier curves defined by 2 points and 2 normals, Bezier curves defined by 4 points, and Bezier surfaces defined by 4x4 points. Methods are provided for calculating forward differences of Bezier curves and surfaces, and computing intermediate points for Bezier curves defined by end points and normals and for the inner points of a Bezier surface given the corner and border points.

Uploaded by

Userxyz123
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
717 views

Bezier-Surfaces C++ Code

The document contains C++ code for calculating intermediate points and derivatives for 3D Bezier curves and surfaces. It includes classes for 3D vectors, Bezier curves defined by 2 points and 2 normals, Bezier curves defined by 4 points, and Bezier surfaces defined by 4x4 points. Methods are provided for calculating forward differences of Bezier curves and surfaces, and computing intermediate points for Bezier curves defined by end points and normals and for the inner points of a Bezier surface given the corner and border points.

Uploaded by

Userxyz123
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Navigations-Leiste Home

C++ Code zur Berechnung der Deltas beim Forward-


Differencing für Bezier-Kurven (4 Punkte)
/* --------------------------------------------------------------------------
3d-vector
for operations in 3d euclidean space
-------------------------------------------------------------------------- */
class vector3d
{
public:
double x;
double y;
double z;

public:
// construct
vector3d (void) { }
vector3d (const class vector3d &v) {
x=v.x; y=v.y; z=v.z; }
vector3d (double x0, double y0, double z0) {
x=x0; y=y0; z=z0; }

// set
virtual void set (const class vector3d &v) {
x=v.x; y=v.y; z=v.z; }
virtual void set (double x0, double y0, double z0) {
x=x0; y=y0; z=z0; }

// set
class vector3d& operator = (const class vector3d &v) {
set(v);
return(*this);
}

// dot operations
class vector3d& operator += (const class vector3d &v) {
x += v.x;
y += v.y;
z += v.z;
return(*this);
}

// ...
};

/* --------------------------------------------------------------------------
3d-bezier curves and surfaces
-------------------------------------------------------------------------- */
class bezier3d {
protected:
// create deltas for forward differencing
virtual void forwdiff
(long steps, // number of steps p1...p4
const class vector3d &p1, // point 1 (start-point)
const class vector3d &z12, // point 2 (intermediate 1)
const class vector3d &z21, // point 3 (intermediate 2)
const class vector3d &p2, // point 4 (end point)
class vector3d &delta1, // out: delta 1
class vector3d &delta2, // out: delta 2
class vector3d &delta3) // out: delta 3
{
double step1 = 1.0 / (double)(steps-1);
-p1.z + 3.0*z12.z - 3.0*p3.z + p2.z);
class vector3d b (3.0*p1.x - 6.0*z12.x + 3.0*z21.x,
3.0*p1.y - 6.0*z12.y + 3.0*z21.y,
3.0*p1.z - 6.0*z12.z + 3.0*z21.z);
class vector3d c (-3.0*p1.x + 3.0*z12.x,
-3.0*p1.y + 3.0*z12.y,
-3.0*p1.z + 3.0*z12.z);

delta1.set (a.x*step3 + b.x*step2 + c.x*step1,


a.y*step3 + b.y*step2 + c.y*step1,
a.z*step3 + b.z*step2 + c.z*step1);
delta2.set (6.0*a.x*step3 + 2.0*b.x*step2,
6.0*a.y*step3 + 2.0*b.y*step2,
6.0*a.z*step3 + 2.0*b.z*step2);
delta3.set (6.0*a.x*step3,
6.0*a.y*step3,
6.0*a.z*step3);
}

// ...
}
C++ Code zur Berechnung der Zwischenpunkte aus den zwei
Eckpunkten und zwei Normalenvektoren
/* --------------------------------------------------------------------------
3d-bezier-curve
2 points and 2 normal vectors
-------------------------------------------------------------------------- */
class bezier_curve_2p2n : public bezier_curve_4p {

public:

// create intermediat points p1...p2: p1 p12 p21 p2


virtual void intermediates (const class vector3d &p1, // point 1
const class vector3d &n1, // normal vector at p1
const class vector3d &p2, // point 2
const class vector3d &n2, // normal vector at p2
class vector3d &p12, // (OUT)
class vector3d &p21, // (OUT)
double h=1.0) const // distance factor
{
// lines p2+t*n1 / p1+t*n2
class line3d l1 (p2,n1);
class line3d l2 (p1,n2);

// tangential planes for p1 / p2


class plane3d e1 (n1,p1);
class plane3d e2 (n2,p2);

// dist |p1-p2|
double d12 = p1.dist (p2);

// intermediate points: p1 p12 p21 p2


p12 = e1.intersection (l1);
p21 = e2.intersection (l2);

class vector3d v12 (p2-p1);

// set point distance to max 1/3 of |p1-p2|


double f = 1.0/(3.0*ABS(v12.cosinus(p1-p12))) * h;
double g = 1.0/(3.0*ABS(v12.cosinus(p2-p21))) * h;
p12 -= p1; p12 *= MIN(1.0,(d12/p12.length())*f); p12 += p1;
p21 -= p2; p21 *= MIN(1.0,(d12/p21.length())*g); p21 += p2;

// take p1 / p2 itself when p12 / p21 is not valid


if (!p12.isvalid()) p12.set (p1);
if (!p21.isvalid()) p21.set (p2);
}
};
C++ Code zur Berechnung der Deltas beim Forward-
Differencing für Bezier-Oberflächen (4x4 Punkte)
/* --------------------------------------------------------------------------
3d-bezier-surface
4x4 points
-------------------------------------------------------------------------- */
class bezier_surface_4x4p {

public:

class vector3d point; // current point

protected:

class vector3d delta1;


class vector3d delta2;
class vector3d delta3;
class vector3d delta[4][4];

protected:

// calculate forward differences


virtual void forwdiff (long xsteps, long ysteps,
const class vector3d p[4][4])
{
double x = 1.0 / (double)(xsteps-1);
double x2 = x*x, x3 = x2*x;

double y = 1.0 / (double)(ysteps-1);


double y2 = y*y, y3 = y2*y;

double s[4][4] = {
{ 1.00, 0.00, 0.00, 0.00 },
{ ( -1.0*x3 + 3.0*x2 - 3.0*x), ( 3.0*x3 - 6.0*x2 + 3.0*x),
( -3.0*x3 + 3.0*x2), ( 1.0*x3) },
{ ( -6.0*x3 + 6.0*x2), ( 18.0*x3 - 12.0*x2),
(-18.0*x3 + 6.0*x2), ( 6.0*x3) },
{ ( -6.0*x3), ( 18.0*x3), (-18.0*x3), ( 6.0*x3) }
};
double t[4][4] = {
{ 1.00, (-1.0*y3 + 3.0*y2 - 3.0*y), (-6.0*y3 + 6.0*y2), ( -6.0*y3) },
{ 0.00, ( 3.0*y3 - 6.0*y2 + 3.0*y), (18.0*y3 - 12.0*y2), ( 18.0*y3) },
{ 0.00, (-3.0*y3 + 3.0*y2), (-18.0*y3 + 6.0*y2), (-18.0*y3) },
{ 0.00, (1.0*y3), ( 6.0*y3), ( 6.0*y3) }
};

class vector3d tdelta[4][4];


matmult (p, t, tdelta);
matmult (s, tdelta, delta);

point = delta[0][0];
delta1 = delta[0][1];
delta2 = delta[0][2];
delta3 = delta[0][3];
}

// matrix multiplication c = a * b
virtual void matmult (double a[4][4], const class vector3d b[4][4],
class vector3d c[4][4]) {
for (long i,y=0; y<4; y++)
for (long x=0; x<4; x++)
for (long x=0; x<4; x++)
for (i=0, c[x][y]=0; i<4; i++) { c[x][y] += (a[x][i]*b[i][y]); }
}

public :

// cunstruct / set
bezier_surface_4x4p (void) { }
bezier_surface_4x4p (const bezier_surface_4x4p &s) { set (s); }
bezier_surface_4x4p (const class vector3d p[4][4],
long xsteps, long ysteps) { set (p,xsteps,ysteps); }
virtual void set (const bezier_surface_4x4p &s) {
point = s.point; delta1 = s.delta1; delta2 = s.delta2; delta3 = s.delta3;
for (long y=0; y<4; y++)
for (long x=0; x<4; x++) delta[x][y] = s.delta[x][y]; }
virtual void set (const class vector3d p[4][4],
long xsteps, long ysteps) { forwdiff (xsteps,ysteps,p); }

// next row / column (rows first)


virtual void nextrow (void) {
point += delta1; delta1 += delta2; delta2 += delta3; }
virtual void nextcol (void) {
for (long y=0; y<4; y++)
for (long x=0; x<3; x++) delta[x][y] += delta[x+1][y];
point = delta[0][0];
delta1 = delta[0][1];
delta2 = delta[0][2];
delta3 = delta[0][3];
}
};
C++ Code zur Berechnung der Hilfspunkte einer Bezier-Fläche
/* --------------------------------------------------------------------------
3d-bezier-surface
4 points + 4 normal vectors
-------------------------------------------------------------------------- */

class bezier_surface_4p4n : public bezier_surface_4x4p {


protected:

// border intermediates
// n : normals for corners p[0][0], p[3][0], p[3][3], p[0][3]
// h : intermediate point distance factor (<1:flat, >1:round)
// p : pre: corners filled in (IN/OUT)
virtual void outer (const class vector3d n[4], doubleh[4],
class vector3d p[4][4]) const
{
// ... border
class bezier_curve_2p2n bc;
bc.intermediates (p[0][0],n[0], p[3][0],n[1], p[1][0],p[2][0], h[0]);
bc.intermediates (p[0][3],n[3], p[3][3],n[2], p[1][3],p[2][3], h[2]);
bc.intermediates (p[0][0],n[0], p[0][3],n[3], p[0][1],p[0][2], h[3]);
bc.intermediates (p[3][0],n[1], p[3][3],n[2], p[3][1],p[3][2], h[1]);
}

// inner intermediates
// p : pre: corners / border points filled in (IN/OUT)
virtual void inner (class vector3d p[4][4]) const
{
p[1][1] = inner (p[0][3],p[0][1],p[0][0],p[1][0],p[3][0],
p[3][1],p[3][3],p[1][3]);
p[2][1] = inner (p[0][0],p[2][0],p[3][0],p[3][1],p[3][3],
p[2][3],p[0][3],p[0][1]);
p[2][2] = inner (p[3][0],p[3][2],p[3][3],p[2][3],p[0][3],
p[0][2],p[0][0],p[2][0]);
p[1][2] = inner (p[3][3],p[1][3],p[0][3],p[0][2],p[0][0],
p[1][0],p[3][0],p[3][2]);
}

// inner intermediate point for point 2


//
// p1 ... p12 p2
// res p23
// ...
// p3
virtual class vector3d inner (const class vector3d &p1,
const class vector3d &p12,
const class vector3d &p2,
const class vector3d &p23,
const class vector3d &p3,
const class vector3d &p34,
const class vector3d &p4,
const class vector3d &p14) const
{
// use p4 and p14 instead of p1 / p3 if p2==p1 / p2==p3
const class vector3d *v1 = &p1, *v12 = &p12, *v3 = &p3, *v23 = &p23;
if (p1==p2) { v1 = &p4; v12 = &p14; }
if (p2==p3) { v3 = &p4; v23 = &p34; }

// lines p1 - p2 / p2 -p3
class line3d l12 (p2,p2-*v1);
class line3d l23 (p2,p2-*v3);
// tangential planes at p12 / p23
class plane3d e12 (i12-*v12,*v12);
class plane3d e23 (i23-*v23,*v23);

// intersection line between planes e12 / e23


class line3d l (e12.intersection (e23));

// extend p2 - v12 and p2 - v23


class vector3d c12 (*v12-p2);
class vector3d c23 (*v23-p2);
double f = 2.0 - c12.cosinus(c23);
class vector3d x12 (p2 + (c12*f));
class vector3d x23 (p2 + (c23*f));

// result
class vector3d res ((l.projection (x12)+l.projection (x23))/2.0);
if (!res.isvalid()) res = (*v12+*v23-p2);
return (res);
}

public:

// create intermediate points


// construct / set
// p : corner points p[0] p[1]
// p[3] p[2]
// n : normal vectors at corner points
// h : intermediate point distance factor (<1:flat, >1:round)
virtual void intermediates (const class vector3d p[4],
const class vector3d n[4],
class vector3d p16[4][4]) const
{
double h[4]={1.0,1.0,1.0,1.0};
intermediates (p,n,p16,h);
}
virtual void intermediates (const class vector3d p[4],
const class vector3d n[4],
class vector3d p16[4][4],
double h[4]) const
{
// corners
p16[0][0] = p[0];
p16[3][0] = p[1];
p16[0][3] = p[3];
p16[3][3] = p[2];
// intermediates ...
// ... border
outer (n,h,p16);
// ... inner
inner (p16);
}
// ...
};

You might also like