Bezier-Surfaces C++ Code
Bezier-Surfaces C++ Code
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);
// ...
}
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:
// dist |p1-p2|
double d12 = p1.dist (p2);
public:
protected:
protected:
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) }
};
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); }
// 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]);
}
// 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);
// result
class vector3d res ((l.projection (x12)+l.projection (x23))/2.0);
if (!res.isvalid()) res = (*v12+*v23-p2);
return (res);
}
public: