Sketcher: BSpline simplified endpoint tangency/perpendicularity solver implementation

=====================================================================================

Support for tangency/perpendicularity using angle via point for BSpline with appropriate
endpoint multiplicity so that the endpoints goes thru the first and last poles (control points).

Warning: Not applicable to periodic BSplines.
Warning: Not applicable to any non-periodic BSpline with inappropriate endpoint conditions.
This commit is contained in:
Abdullah Tahiri 2017-01-14 23:29:32 +01:00
parent 9bf1e8f4f4
commit e53dc90c9a
2 changed files with 58 additions and 1 deletions

View File

@ -611,7 +611,49 @@ ArcOfParabola* ArcOfParabola::Copy()
DeriVector2 BSpline::CalculateNormal(Point& p, double* derivparam) DeriVector2 BSpline::CalculateNormal(Point& p, double* derivparam)
{ {
// place holder // place holder
DeriVector2 ret = DeriVector2(); DeriVector2 ret;
if (mult[0] > degree && mult[mult.size()-1] > degree) {
// if endpoints thru end poles
if(*p.x == *start.x && *p.y == *start.y) {
// and you are asking about the normal at start point
// then tangency is defined by first to second poles
DeriVector2 endpt(this->poles[1], derivparam);
DeriVector2 spt(this->poles[0], derivparam);
DeriVector2 npt(this->poles[2], derivparam); // next pole to decide normal direction
DeriVector2 tg = endpt.subtr(spt);
DeriVector2 nv = npt.subtr(spt);
if ( tg.scalarProd(nv) > 0 )
ret = tg.rotate90cw();
else
ret = tg.rotate90ccw();
}
else if(*p.x == *end.x && *p.y == *end.y) {
// and you are asking about the normal at end point
// then tangency is defined by last to last but one poles
DeriVector2 endpt(this->poles[poles.size()-1], derivparam);
DeriVector2 spt(this->poles[poles.size()-2], derivparam);
DeriVector2 npt(this->poles[poles.size()-3], derivparam); // next pole to decide normal direction
DeriVector2 tg = endpt.subtr(spt);
DeriVector2 nv = npt.subtr(spt);
if ( tg.scalarProd(nv) > 0 )
ret = tg.rotate90ccw();
else
ret = tg.rotate90cw();
} else {
// another point and we have no clue until we implement De Boor
ret = DeriVector2();
}
}
else {
// either periodic or abnormal endpoint multiplicity, we have no clue so currently unsupported
ret = DeriVector2();
}
return ret; return ret;
} }

View File

@ -2298,6 +2298,21 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
return; return;
} }
// This code supports simple bspline endpoint tangency to any other geometric curve
const Part::Geometry *geom1 = Obj->getGeometry(GeoId1);
const Part::Geometry *geom2 = Obj->getGeometry(GeoId2);
if( geom1 && geom2 &&
( geom1->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() ||
geom2->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() )){
if(geom1->getTypeId() != Part::GeomBSplineCurve::getClassTypeId()) {
std::swap(GeoId1,GeoId2);
std::swap(PosId1,PosId2);
}
// GeoId1 is the bspline now
} // end of code supports simple bspline endpoint tangency
openCommand("add tangent constraint"); openCommand("add tangent constraint");
Gui::Command::doCommand( Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d,%d)) ", Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d,%d)) ",