extrusion

This commit is contained in:
Joachim Schoeberl 2009-04-14 19:20:09 +00:00
parent 08ea2e9639
commit 6222d32e34
6 changed files with 319 additions and 233 deletions

View File

@ -125,31 +125,9 @@ namespace netgen
}
#define NEWJS
void ExtrusionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d,
int & seg, double & t) const
{
#ifdef NEWJS
// JS Version
double mindist = 0;
for (int i = 0; i < path->GetNSplines(); i++)
{
Point<2> hpoint2d;
double ht = CalcProj (point3d, hpoint2d, i);
double hdist = Dist2(point3d, p0[i]);
if (i == 0 || hdist < mindist)
{
seg = i;
t = ht;
mindist = hdist;
point2d = hpoint2d;
latest_seg = i;
}
}
return;
#endif
#ifdef OLDWM
if (Dist2 (point3d, latest_point3d) <
1e-25 * Dist2(path->GetSpline(0).StartPI(), path->GetSpline(0).EndPI()))
{
@ -176,6 +154,8 @@ namespace netgen
Point<3> startp(path->GetSpline(i).StartPI());
Point<3> endp(path->GetSpline(i).EndPI());
Point<3> tanp(spline3_path[i]->TangentPoint());
/*
double da,db,dc;
Vec<3> dir = endp-startp;
@ -211,16 +191,29 @@ namespace netgen
dc = Dist(endp,point3d);
else
dc = sqrt(topoint.Length2() - s*s);
// da = sqrt (MinDistLP2 (startp, endp, point3d));
// db = sqrt (MinDistLP2 (startp, tanp, point3d));
// dc = sqrt (MinDistLP2 (endp, tanp, point3d));
auxmin = min3(da,db,dc);
if(da > db && da > dc)
auxcut = da;
else
auxcut = max2(da,min2(db,dc));
*/
auxmin = min3(da,db,dc);
// lower bound for dist
auxmin = sqrt (MinDistTP2 (startp, endp, tanp, point3d));
// upper bound for dist
auxcut = min2 (Dist (startp, point3d), Dist (endp, point3d));
}
else if(line_path[i])
{
/*
double l;
Vec<3> dir = path->GetSpline(i).EndPI() - path->GetSpline(i).StartPI();
l = dir.Length(); dir *= 1./l;
@ -228,22 +221,21 @@ namespace netgen
double s = topoint * dir;
if(s<=0)
auxcut = topoint.Length();
else if(s>=l)
else if(s>=l)
auxcut = Dist(path->GetSpline(i).EndPI(),point3d);
else
auxcut = sqrt(topoint.Length2() - s*s);
auxmin = auxcut;
*/
auxmin = auxcut = sqrt (MinDistLP2 (path->GetSpline(i).StartPI(),
path->GetSpline(i).EndPI(),
point3d));
}
mindist[i] = auxmin;
if(i==0 || auxcut < cutdist)
cutdist = auxcut;
/*
double d1 = Dist2(point3d,path.GetSpline(i).StartPI());
@ -278,7 +270,6 @@ namespace netgen
for(int i=0; i<path->GetNSplines(); i++)
{
if(mindist[i] > cutdist) continue;
//(*testout) << i << " ";
double thist = CalcProj(point3d,testpoint2d,i);
testpoint3d = p0[i] + testpoint2d(0)*x_dir[i] + testpoint2d(1)*loc_z_dir[i];
@ -300,7 +291,6 @@ namespace netgen
}
//(*testout) << endl;
//(*testout) << " t " << t << endl;
#endif
}
double ExtrusionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d,
@ -335,6 +325,8 @@ namespace netgen
return t;
}
double ExtrusionFace :: CalcFunctionValue (const Point<3> & point) const
{
Point<2> p;
@ -342,60 +334,58 @@ namespace netgen
double dummyd;
int dummyi;
CalcProj(point,p,dummyi,dummyd);
//(*testout) << "spline " << dummyi << " t " << dummyd << endl;
CalcProj(point, p, dummyi, dummyd);
return profile_spline_coeff(0)*p(0)*p(0) + profile_spline_coeff(1)*p(1)*p(1)
+ profile_spline_coeff(2)*p(0)*p(1) + profile_spline_coeff(3)*p(0)
+ profile_spline_coeff(4)*p(1) + profile_spline_coeff(5);
return
profile_spline_coeff(0)*p(0)*p(0) +
profile_spline_coeff(1)*p(1)*p(1) +
profile_spline_coeff(2)*p(0)*p(1) +
profile_spline_coeff(3)*p(0) +
profile_spline_coeff(4)*p(1) +
profile_spline_coeff(5);
}
void ExtrusionFace :: CalcGradient (const Point<3> & point, Vec<3> & grad) const
{
int i;
Point<2> p2d;
double t_path;
int seg;
CalcProj(point,p2d,seg,t_path);
CalcProj (point, p2d, seg, t_path);
Point<3> phi;
Vec<3> phip,phipp,phi_minus_point;
path->GetSpline(seg).GetDerivatives(t_path,phi,phip,phipp);
Vec<3> phip, phipp, phi_minus_point;
path->GetSpline(seg).GetDerivatives(t_path, phi, phip, phipp);
phi_minus_point = phi-point;
Vec<3> grad_t = phip;
double facA = phipp*phi_minus_point + phip*phip;
grad_t *= 1./facA;
Vec<3> grad_t = (1.0/(phipp*phi_minus_point + phip*phip)) * phip;
Array < Vec<3> > dphi_dX(3);
Vec<3> dphi_dX[3];
Vec<3> dy_dir_dX[3];
Vec<3> dx_dir_dX[3];
for(i=0; i<3; i++)
for(int i = 0; i < 3; i++)
dphi_dX[i] = grad_t(i)*phip;
Array < Vec<3> > dy_dir_dX(3);
double lphip = phip.Length();
Vec<3> dy_dir_dt = (1./lphip) * phipp - ((phip*phipp)/pow(lphip,3)) * phip;
dy_dir_dX[0] = dy_dir_dX[1] = dy_dir_dX[2] =
(1./lphip) * phipp - ((phip*phipp)/pow(lphip,3)) * phip;
Vec<3> dx_dir_dt = Cross(dy_dir_dt,z_dir[seg]);
for(i=0; i<3; i++)
dy_dir_dX[i] *= grad_t(i);
for(int i = 0; i < 3; i++)
dy_dir_dX[i] = grad_t(i) * dy_dir_dt;
for(int i = 0; i < 3; i++)
dx_dir_dX[i] = grad_t(i) * dx_dir_dt;
Array < Vec<3> > dx_dir_dX(3);
for(i=0; i<3; i++)
dx_dir_dX[i] = Cross(dy_dir_dX[i],z_dir[seg]);
Vec<3> grad_xbar;
for(i=0; i<3; i++)
for(int i=0; i<3; i++)
grad_xbar(i) = -1.*(phi_minus_point * dx_dir_dX[i]) + x_dir[seg](i) - x_dir[seg] * dphi_dX[i];
double zy = z_dir[seg]*y_dir[seg];
@ -403,20 +393,81 @@ namespace netgen
Vec<3> grad_ybar;
Vec<3> aux = z_dir[seg] - zy*y_dir[seg];
for(i=0; i<3; i++)
for(int i=0; i<3; i++)
grad_ybar(i) = ( (z_dir[seg]*dy_dir_dX[i])*y_dir[seg] + zy*dy_dir_dX[i] ) * phi_minus_point +
aux[i] -
aux * dphi_dX[i];
const double dFdxbar = 2.*profile_spline_coeff(0)*p2d(0) +
double dFdxbar = 2.*profile_spline_coeff(0)*p2d(0) +
profile_spline_coeff(2)*p2d(1) + profile_spline_coeff(3);
const double dFdybar = 2.*profile_spline_coeff(1)*p2d(1) +
double dFdybar = 2.*profile_spline_coeff(1)*p2d(1) +
profile_spline_coeff(2)*p2d(0) + profile_spline_coeff(4);
grad = dFdxbar * grad_xbar + dFdybar * grad_ybar;
/*
{
cout << "grad_xbar = " << grad_xbar << endl;
cout << "grad_ybar = " << grad_ybar << endl;
Vec<3> numgradx, numgrady;
for (int i = 0; i < 3; i++)
{
Point<3> hpl = point, hpr = point;
hpl(i) -= 1e-6; hpr(i) += 1e-6;
Point<2> p2dl, p2dr;
CalcProj (hpl, p2dl, seg, t_path);
CalcProj (hpr, p2dr, seg, t_path);
numgradx(i) = (p2dr(0)-p2dl(0)) / (2e-6);
numgrady(i) = (p2dr(1)-p2dl(1)) / (2e-6);
}
cout << "num grad_xbar" << numgradx << endl;
cout << "num grad_ybar" << numgrady << endl;
}
{
cout << "grad = " << grad << " =?= ";
Vec<3> numgrad;
for (int i = 0; i < 3; i++)
{
Point<3> hpl = point;
Point<3> hpr = point;
hpl(i) -= 1e-6;
hpr(i) += 1e-6;
double vall = CalcFunctionValue (hpl);
double valr = CalcFunctionValue (hpr);
numgrad(i) = (valr - vall) / (2e-6);
}
cout << " numgrad = " << numgrad << endl;
for (int i = 0; i < 3; i++)
{
Point<3> hpl = point;
Point<3> hpr = point;
hpl(i) -= 1e-4;
hpr(i) += 1e-4;
double vall = CalcFunctionValue (hpl);
double valr = CalcFunctionValue (hpr);
numgrad(i) = (valr - vall) / (2e-4);
}
cout << " numgrad2 = " << numgrad << endl;
}
static int cnt = 0;
cnt++;
if (cnt == 10000)
exit (0);
*/
}
void ExtrusionFace :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const
@ -534,7 +585,7 @@ namespace netgen
//(*testout) << "box.Center() " << box.Center() << " projected " << center << " diam " << box.Diam()
// << " dist " << Dist(box.Center(),center) << endl;
return (Dist(box.Center(),center) < 1*box.Diam());
return (Dist(box.Center(),center) < 0.5*box.Diam());
}

View File

@ -16,8 +16,8 @@
*/
#undef DEVELOP
//#define DEVELOP
// #undef DEVELOP
// #define DEVELOP
namespace netgen

View File

@ -36,164 +36,222 @@ namespace netgen
template<int D>
void SplineSeg3<D> :: Project (const Point<D> point, Point<D> & point_on_curve, double & t) const
{
double t_old = -1;
template<int D>
void SplineSeg3<D> :: Project (const Point<D> point, Point<D> & point_on_curve, double & t) const
{
double t_old = -1;
if(proj_latest_t > 0. && proj_latest_t < 1.)
t = proj_latest_t;
else
t = 0.5;
if(proj_latest_t > 0. && proj_latest_t < 1.)
t = proj_latest_t;
else
t = 0.5;
Point<D> phi;
Vec<D> phip,phipp,phimp;
Point<D> phi;
Vec<D> phip,phipp,phimp;
int i=0;
int i=0;
while(t > -0.5 && t < 1.5 && i<20 && fabs(t-t_old) > 1e-15 )
{
GetDerivatives(t,phi,phip,phipp);
while(t > -0.5 && t < 1.5 && i<20 && fabs(t-t_old) > 1e-15 )
{
GetDerivatives(t,phi,phip,phipp);
t_old = t;
t_old = t;
phimp = phi-point;
phimp = phi-point;
//t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.);
t -= (phip*phimp)/(phipp*phimp + phip*phip);
//t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.);
t -= (phip*phimp)/(phipp*phimp + phip*phip);
i++;
}
i++;
}
//if(i<10 && t > 0. && t < 1.)
if(i<20 && t > -0.4 && t < 1.4)
{
if(t < 0)
{
t = 0.;
}
if(t > 1)
{
t = 1.;
}
//if(i<10 && t > 0. && t < 1.)
if(i<20 && t > -0.4 && t < 1.4)
{
if(t < 0)
{
t = 0.;
}
if(t > 1)
{
t = 1.;
}
point_on_curve = SplineSeg3<D>::GetPoint(t);
point_on_curve = SplineSeg3<D>::GetPoint(t);
double dist = Dist(point,point_on_curve);
double dist = Dist(point,point_on_curve);
phi = SplineSeg3<D> ::GetPoint(0);
double auxdist = Dist(phi,point);
if(auxdist < dist)
{
t = 0.;
point_on_curve = phi;
dist = auxdist;
}
phi = SplineSeg3<D> ::GetPoint(1);
auxdist = Dist(phi,point);
if(auxdist < dist)
{
t = 1.;
point_on_curve = phi;
dist = auxdist;
}
}
else
{
double t0 = 0;
double t1 = 0.5;
double t2 = 1.;
phi = SplineSeg3<D> ::GetPoint(0);
double auxdist = Dist(phi,point);
if(auxdist < dist)
{
t = 0.;
point_on_curve = phi;
dist = auxdist;
}
phi = SplineSeg3<D> ::GetPoint(1);
auxdist = Dist(phi,point);
if(auxdist < dist)
{
t = 1.;
point_on_curve = phi;
dist = auxdist;
}
}
else
{
double t0 = 0;
double t1 = 0.5;
double t2 = 1.;
double d0,d1,d2;
double d0,d1,d2;
//(*testout) << "newtonersatz" << endl;
while(t2-t0 > 1e-8)
{
//(*testout) << "newtonersatz" << endl;
while(t2-t0 > 1e-8)
{
phi = SplineSeg3<D> ::GetPoint(t0); d0 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t1); d1 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t2); d2 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t0); d0 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t1); d1 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t2); d2 = Dist(phi,point);
double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2);
double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2);
if(a <= 0)
{
if(d0 < d2)
t2 -= 0.3*(t2-t0);
else
t0 += 0.3*(t2-t0);
if(a <= 0)
{
if(d0 < d2)
t2 -= 0.3*(t2-t0);
else
t0 += 0.3*(t2-t0);
t1 = 0.5*(t2+t0);
}
else
{
double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0);
t1 = 0.5*(t2+t0);
}
else
{
double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0);
double auxt1 = -0.5*b/a;
double auxt1 = -0.5*b/a;
if(auxt1 < t0)
{
t2 -= 0.4*(t2-t0);
t0 = max2(0.,t0-0.1*(t2-t0));
}
else if (auxt1 > t2)
{
t0 += 0.4*(t2-t0);
t2 = min2(1.,t2+0.1*(t2-t0));
}
else
{
t1 = auxt1;
auxt1 = 0.25*(t2-t0);
t0 = max2(0.,t1-auxt1);
t2 = min2(1.,t1+auxt1);
}
if(auxt1 < t0)
{
t2 -= 0.4*(t2-t0);
t0 = max2(0.,t0-0.1*(t2-t0));
}
else if (auxt1 > t2)
{
t0 += 0.4*(t2-t0);
t2 = min2(1.,t2+0.1*(t2-t0));
}
else
{
t1 = auxt1;
auxt1 = 0.25*(t2-t0);
t0 = max2(0.,t1-auxt1);
t2 = min2(1.,t1+auxt1);
}
t1 = 0.5*(t2+t0);
}
t1 = 0.5*(t2+t0);
}
}
}
phi = SplineSeg3<D> ::GetPoint(t0); d0 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t1); d1 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t2); d2 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t0); d0 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t1); d1 = Dist(phi,point);
phi = SplineSeg3<D> ::GetPoint(t2); d2 = Dist(phi,point);
double mind = d0;
t = t0;
if(d1 < mind)
{
t = t1;
mind = d1;
}
if(d2 < mind)
{
t = t2;
mind = d2;
}
double mind = d0;
t = t0;
if(d1 < mind)
{
t = t1;
mind = d1;
}
if(d2 < mind)
{
t = t2;
mind = d2;
}
point_on_curve = SplineSeg3<D> ::GetPoint(t);
}
//(*testout) << " latest_t " << proj_latest_t << " t " << t << endl;
point_on_curve = SplineSeg3<D> ::GetPoint(t);
}
//(*testout) << " latest_t " << proj_latest_t << " t " << t << endl;
proj_latest_t = t;
proj_latest_t = t;
/*
/*
// test it by trivial sampling
double ht;
Point<D> hp;
ProjectTrivial (*this, point, hp, ht);
if (fabs (t-ht) > 1e-3)
double ht;
Point<D> hp;
ProjectTrivial (*this, point, hp, ht);
if (fabs (t-ht) > 1e-3)
{
// if (Dist2 (point, hp) < Dist2 (point, point_on_curve))
cout << "project is wrong" << endl;
cout << "t = " << t << ", ht = " << ht << endl;
cout << "dist org = " << Dist(point, point_on_curve) << endl;
cout << "dist trivial = " << Dist(point, hp) << endl;
// if (Dist2 (point, hp) < Dist2 (point, point_on_curve))
cout << "project is wrong" << endl;
cout << "t = " << t << ", ht = " << ht << endl;
cout << "dist org = " << Dist(point, point_on_curve) << endl;
cout << "dist trivial = " << Dist(point, hp) << endl;
}
*/
}
*/
}
template<int D>
void SplineSeg3<D> :: GetDerivatives (const double t,
Point<D> & point,
Vec<D> & first,
Vec<D> & second) const
{
Vec<D> v1(p1), v2(p2), v3(p3);
double b1 = (1.-t)*(1.-t);
double b2 = sqrt(2.)*t*(1.-t);
double b3 = t*t;
double w = b1+b2+b3;
b1 *= 1./w; b2 *= 1./w; b3 *= 1./w;
double b1p = 2.*(t-1.);
double b2p = sqrt(2.)*(1.-2.*t);
double b3p = 2.*t;
const double wp = b1p+b2p+b3p;
const double fac1 = wp/w;
b1p *= 1./w; b2p *= 1./w; b3p *= 1./w;
const double b1pp = 2.;
const double b2pp = -2.*sqrt(2.);
const double b3pp = 2.;
const double wpp = b1pp+b2pp+b3pp;
const double fac2 = (wpp*w-2.*wp*wp)/(w*w);
for(int i=0; i<D; i++)
point(i) = b1*p1(i) + b2*p2(i) + b3*p3(i);
first = (b1p - b1*fac1) * v1 +
(b2p - b2*fac1) * v2 +
(b3p - b3*fac1) * v3;
/*
second = (b1pp/w - b1p*fac1 - b1*fac2) * v1 +
(b2pp/w - b2p*fac1 - b2*fac2) * v2 +
(b3pp/w - b3p*fac1 - b3*fac2) * v3;
*/
// JS: 2 was missing
second = (b1pp/w - 2*b1p*fac1 - b1*fac2) * v1 +
(b2pp/w - 2*b2p*fac1 - b2*fac2) * v2 +
(b3pp/w - 2*b3p*fac1 - b3*fac2) * v3;
}
template class SplineSeg3<2>;

View File

@ -566,47 +566,6 @@ inline Point<D> SplineSeg3<D> :: GetPoint (double t) const
template<int D>
void SplineSeg3<D> :: GetDerivatives (const double t,
Point<D> & point,
Vec<D> & first,
Vec<D> & second) const
{
Vec<D> v1(p1), v2(p2), v3(p3);
double b1 = (1.-t)*(1.-t);
double b2 = sqrt(2.)*t*(1.-t);
double b3 = t*t;
double w = b1+b2+b3;
b1 *= 1./w; b2 *= 1./w; b3 *= 1./w;
double b1p = 2.*(t-1.);
double b2p = sqrt(2.)*(1.-2.*t);
double b3p = 2.*t;
const double wp = b1p+b2p+b3p;
const double fac1 = wp/w;
b1p *= 1./w; b2p *= 1./w; b3p *= 1./w;
const double b1pp = 2.;
const double b2pp = -2.*sqrt(2.);
const double b3pp = 2.;
const double wpp = b1pp+b2pp+b3pp;
const double fac2 = (wpp*w-2.*wp*wp)/(w*w);
for(int i=0; i<D; i++)
point(i) = b1*p1(i) + b2*p2(i) + b3*p3(i);
first = (b1p - b1*fac1) * v1 +
(b2p - b2*fac1) * v2 +
(b3p - b3*fac1) * v3;
second = (b1pp/w - b1p*fac1 - b1*fac2) * v1 +
(b2pp/w - b2p*fac1 - b2*fac2) * v2 +
(b3pp/w - b3p*fac1 - b3*fac2) * v3;
}
template<int D>
Vec<D> SplineSeg3<D> :: GetTangent (const double t) const

View File

@ -65,14 +65,17 @@ extern double ComputeCylinderRadius (const Point3d & p1, const Point3d & p2,
extern double ComputeCylinderRadius (const Vec3d & n1, const Vec3d & n2,
double h1, double h2);
/// Minimal distance of point p to the line segment [lp1,lp2]
extern double MinDistLP2 (const Point2d & lp1, const Point2d & lp2, const Point2d & p);
/// Minimal distance of point p to the line segment [lp1,lp2]
extern double MinDistLP2 (const Point3d & lp1, const Point3d & lp2, const Point3d & p);
/// Minimal distance of point p to the triangle segment [tp1,tp2,pt3]
extern double MinDistTP2 (const Point3d & tp1, const Point3d & tp2,
const Point3d & tp3, const Point3d & p);
/// Minimal distance of the 2 lines [l1p1,l1p2] and [l2p1,l2p2]
extern double MinDistLL2 (const Point3d & l1p1, const Point3d & l1p2,
const Point3d & l2p1, const Point3d & l2p2);

View File

@ -443,3 +443,18 @@ extern "C" {
DLL_HEADER int Ng_GetElementClosureNodes (int dim, int elementnr, int nodeset, int * nodes);
}
#ifdef __cplusplus
#include <iostream>
namespace netgen
{
DLL_HEADER extern std::ostream * testout;
DLL_HEADER extern int printmessage_importance;
}
#endif