/*
--------------------------------------------------------------------------
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);
//
projections border-intermediate-points on to lines l12 / l23
class
vector3d i12
(l12.projection (*v12));
class
vector3d i23
(l23.projection (*v23));
//
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);
}
// ...
}; |