Beispiel #1
0
void intersectcurves(SplineCurve* cv1, SplineCurve* cv2, double epsge,
		     vector<std::pair<double,double> >& intersections)
  //************************************************************************
  // 
  // Intersect two spline curves. Collect intersection parameters.
  //
  //***********************************************************************
{

  // Make sisl curves and call sisl.
  SISLCurve *pc1 = Curve2SISL(*cv1, false);
  SISLCurve *pc2 = Curve2SISL(*cv2, false);

  int kntrack = 0;
  int trackflag = 0;  // Do not make tracks.
  SISLTrack **track =0;
  int knpt=0, kncrv=0;
  double *par1=0, *par2=0;
  int *pretop = 0;
  SISLIntcurve **intcrvs = 0;
  int stat = 0;
  sh1857(pc1, pc2, 0.0, epsge, trackflag, &kntrack, &track,
	 &knpt, &par1, &par2, &pretop, &kncrv, &intcrvs, &stat);

  ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);


  // Remember intersections points. The intersection curves are
  // skipped.
  int ki;
  for (ki=0; ki<knpt; ki++)
    {
      intersections.push_back(std::make_pair(par1[ki],par2[ki]));
    }

  if (kncrv > 0)
    freeIntcrvlist(intcrvs, kncrv);

  if (par1 != 0) free(par1);
  if (par2 != 0) free(par2);
  if (pretop != 0) free(pretop);
  if (pc1 != 0) freeCurve(pc1);
  if (pc2 != 0) freeCurve(pc2);
}
 void intersectCurveSurf(SplineCurve *cv, SplineSurface *sf,
			 double epsge, 
			 vector<pair<double, Point> >& int_pts,
			 vector<int>& pretopology,
			 vector<pair<pair<double,Point>, 
			 pair<double,Point> > >& int_crvs)
 {
   SISLSurf* sislsf = GoSurf2SISL(*sf, false);
   SISLCurve* sislcv = Curve2SISL(*cv, false);
   int kntrack = 0;
   int trackflag = 0;  // Do not make tracks.
   SISLTrack **track =0;
   int knpt=0, kncrv=0;
   double *par1=0, *par2=0;
   int *pretop = 0;
   SISLIntcurve **vcrv = 0;
   int stat = 0;

   sh1858(sislsf, sislcv, 0.0, epsge, trackflag, &kntrack, &track,
	  &knpt, &par1, &par2, &pretop, &kncrv, &vcrv, &stat);
   ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);

   // Remember intersections points. 
   int ki;
   for (ki=0; ki<knpt; ki++)
     {
       int_pts.push_back(std::make_pair(par2[ki],
					Point(par1[2*ki],par1[2*ki+1])));
       pretopology.insert(pretopology.end(), pretop+4*ki+2, pretop+4*(ki+1));
       pretopology.insert(pretopology.end(), pretop+4*ki, pretop+4*ki+2);
     }

   // Remember intersection curves
   for (ki=0; ki<kncrv; ++ki)
     {
       int nmb_pt = vcrv[ki]->ipoint;
       Point par1 = Point(vcrv[ki]->epar1[0],vcrv[ki]->epar1[1]);
       Point par2 = Point(vcrv[ki]->epar1[2*(nmb_pt-1)],
			  vcrv[ki]->epar1[2*nmb_pt-1]);
       int_crvs.push_back(std::make_pair(std::make_pair(vcrv[ki]->epar2[0], 
							par1),
					 std::make_pair(vcrv[ki]->epar2[nmb_pt-1],
							par2)));
     }

   if (kncrv > 0)
     freeIntcrvlist(vcrv, kncrv);

   if (par1 != NULL) free(par1);
   if (par2 != NULL) free(par2);
   if (sislsf != NULL) freeSurf(sislsf);
   if (sislcv != NULL) freeCurve(sislcv);
   if (pretop != NULL) free(pretop);
 }
void intersectCurvePoint(const ParamCurve* crv, Point pnt, double epsge,
			 vector<double>& intersections, 
			 vector<pair<double, double> >& int_crvs)
  //************************************************************************
  // 
  // Intersect a curve with a point
  //
  //***********************************************************************
{
  // First make sure that the curve is a spline curve
    ParamCurve* tmpcrv = const_cast<ParamCurve*>(crv);
    SplineCurve* sc = tmpcrv->geometryCurve();
    if (sc == NULL)
        THROW("ParamCurve doesn't have a spline representation.");
    
  // Make sisl curve and call sisl.
  SISLCurve *pc = Curve2SISL(*sc, false);

  int knpt=0, kncrv=0;
  double *par=0;
  SISLIntcurve **vcrv = 0;
  int stat = 0;
  s1871(pc, pnt.begin(), pnt.size(), epsge, &knpt, &par, &kncrv, &vcrv, &stat);
  ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);


  // Remember intersections points. 
  if (knpt > 0)
    intersections.insert(intersections.end(), par, par+knpt);

  // Remember intersection curves
  for (int ki=0; ki<kncrv; ++ki)
    int_crvs.push_back(std::make_pair(vcrv[ki]->epar1[0], vcrv[ki]->epar1[vcrv[ki]->ipoint-1]));

  if (kncrv > 0)
    freeIntcrvlist(vcrv, kncrv);

  if (par != 0) free(par);
  if (pc) freeCurve(pc);

  delete sc;
}
void intersect2Dcurves(const ParamCurve* cv1, const ParamCurve* cv2, double epsge,
		       vector<pair<double,double> >& intersections,
		       vector<int>& pretopology,
		       vector<pair<pair<double,double>, pair<double,double> > >& int_crvs)
  //************************************************************************
  // 
  // Intersect two 2D spline curves. Collect intersection parameters
  // and pretopology information.
  //
  //***********************************************************************
{

  // First make sure that the curves are spline curves.
    ParamCurve* tmpcv1 = const_cast<ParamCurve*>(cv1);
    ParamCurve* tmpcv2 = const_cast<ParamCurve*>(cv2);
    SplineCurve* sc1 = tmpcv1->geometryCurve();
    SplineCurve* sc2 = tmpcv2->geometryCurve();
    if (sc1 == NULL || sc2 == NULL)
        THROW("ParamCurves doesn't have a spline representation.");

    MESSAGE_IF(cv1->dimension() != 2,
		"Dimension different from 2, pretopology not reliable.");

  // Make sisl curves and call sisl.
  SISLCurve *pc1 = Curve2SISL(*sc1, false);
  SISLCurve *pc2 = Curve2SISL(*sc2, false);

  int kntrack = 0;
  int trackflag = 0;  // Do not make tracks.
  SISLTrack **track =0;
  int knpt=0, kncrv=0;
  double *par1=0, *par2=0;
  int *pretop = 0;
  SISLIntcurve **vcrv = 0;
  int stat = 0;
  sh1857(pc1, pc2, 0.0, epsge, trackflag, &kntrack, &track,
	 &knpt, &par1, &par2, &pretop, &kncrv, &vcrv, &stat);

  ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);


  // Remember intersections points. 
  int ki;
  for (ki=0; ki<knpt; ki++)
    {
      intersections.push_back(std::make_pair(par1[ki],par2[ki]));
      pretopology.insert(pretopology.end(), pretop+4*ki, pretop+4*(ki+1));
    }

  // Remember intersection curves
  for (ki=0; ki<kncrv; ++ki)
    int_crvs.push_back(std::make_pair(std::make_pair(vcrv[ki]->epar1[0], vcrv[ki]->epar2[0]), 
				      std::make_pair(vcrv[ki]->epar1[vcrv[ki]->ipoint-1],
						     vcrv[ki]->epar2[vcrv[ki]->ipoint-1])));

  if (kncrv > 0)
    freeIntcrvlist(vcrv, kncrv);

  if (par1 != 0) free(par1);
  if (par2 != 0) free(par2);
  if (pc1 != 0) freeCurve(pc1);
  if (pc2 != 0) freeCurve(pc2);
  if (pretop != 0) free(pretop);

  delete sc1;
  delete sc2;
}
Beispiel #5
0
//===========================================================================
void Curvature::curvatureRadiusPoints(const SplineCurve& curve,
			   double curveRad,
			   vector<double>& pos)
//===========================================================================
{
  
  BsplineBasis basis = curve.basis();
  int order = basis.order();
  int new_order = 6 * order - 11;

  vector<double> knots_simple;
  vector<double> new_knots;
  basis.knotsSimple(knots_simple);

  for (size_t i = 0; i < knots_simple.size(); ++i)
    {
      int old_mult = basis.knotMultiplicity(knots_simple[i]);
      int new_mult = 5 * order - 9 + old_mult;
      if (old_mult >= order-1) new_mult -= 2 - order + old_mult;
      for (int j = 0; j < new_mult; ++j) new_knots.push_back(knots_simple[i]);
    }

  int num_coefs = (int)new_knots.size() - new_order;

  BsplineBasis new_basis(new_order, new_knots.begin(), new_knots.end());

  vector<double> coefs_par; // Parameter values for the coefs (Greville)
  vector<double> coefs;

  shared_ptr<SplineCurve> d_curve(curve.derivCurve(1));
  shared_ptr<SplineCurve> dd_curve(d_curve->derivCurve(1));

  for (int i = 0; i < num_coefs; )
    {
      int knot_pos = i + 1;
      while (knot_pos < int(new_knots.size()) && new_knots[knot_pos-1] == new_knots[knot_pos])
	++knot_pos;
      double step = (new_knots[knot_pos] - new_knots[knot_pos-1]) / double(knot_pos - i);
      double tpar = new_knots[knot_pos-1] + step/2.0;
      for (;i < knot_pos; ++i)
	{
	  coefs_par.push_back(tpar);
	  tpar += step;
	}
    }

  for (int i = 0; i < num_coefs; ++i)
    {
      double tpar = coefs_par[i];
      Point d_p, dd_p;
      d_curve->point(d_p, tpar);
      dd_curve->point(dd_p, tpar);
      double d_p_length2 = d_p.length2();

      coefs.push_back( (d_p % dd_p).length2() * curveRad * curveRad - d_p_length2*d_p_length2*d_p_length2);
    }

  vector<double> curvature_coefs;
  vector<double> dummy_tangents;
  vector<int> dummy_index;
  SplineInterpolator interpolator;
  interpolator.setBasis(new_basis);
  interpolator.interpolate(coefs_par, coefs, dummy_index,
			   dummy_tangents, curvature_coefs);

  // Normalize large values
  double min_val = std::numeric_limits<double>::max();
  double max_val = -std::numeric_limits<double>::max();
  for (size_t kr=0; kr<curvature_coefs.size(); ++kr)
    {
      min_val = std::min(min_val, curvature_coefs[kr]);
      max_val = std::max(max_val, curvature_coefs[kr]);
    }
  
  double lim = 100.0;
  if (max_val-min_val > lim && max_val > 0.0 && min_val < 0.0)
    {
      double fac = lim/(max_val-min_val);
      for (size_t kr=0; kr<curvature_coefs.size(); ++kr)
	curvature_coefs[kr] *= fac;
    }

  shared_ptr<SplineCurve> curvature_curve(
    new SplineCurve(num_coefs, new_order,
		    interpolator.basis().begin(),
		    curvature_coefs.begin(), 1));

  SISLCurve *num_sisl = Curve2SISL(*(curvature_curve.get()), false);
  SISLObject *qo1 = 0;
  SISLObject *qo2 = 0;
  SISLPoint *qp = 0;
  double spoint[1];
  spoint[0] = 0.0;
  int kstat = 0;
  SISLIntdat *qintdat = 0;
  double aepsge = 1.0e-6; //1.0e-9;

  if (!(qo1 = newObject(SISLCURVE))) goto error101;
  qo1 -> c1 = num_sisl;
  qo1 -> o1 = qo1;

  if (!(qo2 = newObject(SISLPOINT))) goto error101;
  spoint[0] = 0.0;
  if(!(qp = newPoint(spoint,1,1))) goto error101;
  qo2 -> p1 = qp;

  sh1761(qo1,qo2,aepsge,&qintdat,&kstat);
  if (kstat < 0) goto error101;

  if (qintdat)
  {
      for (int i = 0; i < qintdat->ipoint; ++i)
	  pos.push_back(qintdat->vpoint[i]->epar[0]);
  }

 error101:
  if (qo1)     freeObject(qo1);
  if (qo2)     freeObject(qo2);
  if (qintdat) freeIntdat(qintdat);
}
Beispiel #6
0
//===========================================================================
bool Curvature::minimalCurvatureRadius(const SplineCurve& curve,
				       double& mincurv,
				       double& pos)
//===========================================================================
{
  // Find the spline function for the numerator in the derivate of the square of the curvature

  BsplineBasis basis = curve.basis();
  int order = basis.order();
  int new_order = 6 * order - 14;

  mincurv = MAXDOUBLE;
  pos = (basis.startparam() + basis.endparam()) / 2.0;
  if (new_order < 0)    // Straight line
    {
      return false;
    }

  vector<double> knots_simple;
  vector<double> new_knots;
  basis.knotsSimple(knots_simple);

  for (size_t i = 0; i < knots_simple.size(); ++i)
    {
      int old_mult = basis.knotMultiplicity(knots_simple[i]);
      int new_mult = 5 * order - 11 + old_mult;
      if (old_mult >= order-2) new_mult -= 3 - order + old_mult;
      for (int j = 0; j < new_mult; ++j) new_knots.push_back(knots_simple[i]);
    }

  int num_coefs = (int)new_knots.size() - new_order;

  BsplineBasis new_basis(new_order, new_knots.begin(), new_knots.end());

  vector<double> coefs_par; // Parameter values for the coefs (Greville)
  vector<double> coefs;

  shared_ptr<SplineCurve> d_curve(curve.derivCurve(1));
  shared_ptr<SplineCurve> dd_curve(d_curve->derivCurve(1));
  shared_ptr<SplineCurve> ddd_curve(dd_curve->derivCurve(1));

  for (int i = 0; i < num_coefs; )
    {
      int knot_pos = i + 1;
      while (knot_pos < int(new_knots.size()) && new_knots[knot_pos-1] == new_knots[knot_pos])
	++knot_pos;
      double step = (new_knots[knot_pos] - new_knots[knot_pos-1]) / double(knot_pos - i);
      double tpar = new_knots[knot_pos-1] + step/2.0;
      for (;i < knot_pos; ++i)
	{
	  coefs_par.push_back(tpar);
	  tpar += step;
	}
    }

  for (int i = 0; i < num_coefs; ++i)
    {
      double tpar = coefs_par[i];
      Point d_p, dd_p, ddd_p;
      d_curve->point(d_p, tpar);
      dd_curve->point(dd_p, tpar);
      ddd_curve->point(ddd_p, tpar);

      coefs.push_back( (d_p % dd_p) * (d_p % (ddd_p * (d_p * d_p) - dd_p * 3 * (d_p * dd_p))) );
    }

  vector<double> numerator_coefs;
  vector<double> dummy_tangents;
  vector<int> dummy_index;
  SplineInterpolator interpolator;
  interpolator.setBasis(new_basis);
  interpolator.interpolate(coefs_par, coefs, dummy_index,
			   dummy_tangents, numerator_coefs);

  shared_ptr<SplineCurve> numerator_curve(
    new SplineCurve(num_coefs, new_order,
		    interpolator.basis().begin(),
		    numerator_coefs.begin(), 1));

  bool mincurvFound = false;
  vector<double> extremalParametervalues;

  extremalParametervalues.push_back(knots_simple[0]);
  for (size_t kr=1; kr<knots_simple.size(); ++kr)
    {
      extremalParametervalues.push_back(knots_simple[kr]);
      shared_ptr<SplineCurve> sub_numerator(numerator_curve->subCurve(knots_simple[kr-1],
								      knots_simple[kr]));
      SISLCurve *num_sisl = Curve2SISL(*(sub_numerator.get()), false);
      SISLObject *qo1 = 0;
      SISLObject *qo2 = 0;
      SISLPoint *qp = 0;
      double spoint[1];
      spoint[0] = 0.0;
      int kstat = 0;
      SISLIntdat *qintdat = 0;
      double aepsge = 1.0e-6; // 1.0e-9;

      // Normalize large values
      double min_val = std::numeric_limits<double>::max();
      double max_val = -std::numeric_limits<double>::max();
      for (int kr=0; kr<num_sisl->in; ++kr)
	{
	  min_val = std::min(min_val, num_sisl->ecoef[kr]);
	  max_val = std::max(max_val, num_sisl->ecoef[kr]);
	}
  
  double lim = 100.0;
  if (max_val-min_val > lim && max_val > 0.0 && min_val < 0.0)
    {
      double fac = lim/(max_val-min_val);
      for (int kr=0; kr<num_sisl->in; ++kr)
	num_sisl->ecoef[kr] *= fac;
    }

      if (!(qo1 = newObject(SISLCURVE)))
	continue;
      qo1 -> c1 = num_sisl;
      qo1 -> o1 = qo1;

      if (!(qo2 = newObject(SISLPOINT)))
	{
	  if (qo1)     freeObject(qo1);
	  continue;
	}
      spoint[0] = 0.0;
      if(!(qp = newPoint(spoint,1,1)))
	{
	  if (qo1)     freeObject(qo1);
	  if (qo2)     freeObject(qo2);
	  continue;
	}
      qo2 -> p1 = qp;

      sh1761(qo1,qo2,aepsge,&qintdat,&kstat);
      if (kstat < 0) 
	{
	  if (qo1)     freeObject(qo1);
	  if (qo2)     freeObject(qo2);
	  if (qintdat) freeIntdat(qintdat);
	  continue;
	}

      if (qintdat)
	{
	  for (int i = 0; i < qintdat->ipoint; ++i)
	    extremalParametervalues.push_back(qintdat->vpoint[i]->epar[0]);
	}
      if (qo1)     freeObject(qo1);
      if (qo2)     freeObject(qo2);
      if (qintdat) freeIntdat(qintdat);
    }

  for (size_t i = 0; i < extremalParametervalues.size(); ++i)
    {
      Point d_p, dd_p;
      d_curve->point(d_p, extremalParametervalues[i]);
      dd_curve->point(dd_p, extremalParametervalues[i]);
      double curv_numerator = (d_p % dd_p).length();
      double curv_denominator = d_p.length();
      curv_denominator = curv_denominator * curv_denominator * curv_denominator;
      if (curv_numerator <= curv_denominator * 1.0e-9) continue;

      double curvatureRadius = curv_denominator/curv_numerator;    // Same as 1/curvature
      if (!mincurvFound || curvatureRadius < mincurv)
	{
	  mincurvFound = true;
	  mincurv = curvatureRadius;
	  pos = extremalParametervalues[i];

	}
    }
  return (extremalParametervalues.size() > 0);
}