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:
parent
9bf1e8f4f4
commit
e53dc90c9a
|
@ -611,7 +611,49 @@ ArcOfParabola* ArcOfParabola::Copy()
|
|||
DeriVector2 BSpline::CalculateNormal(Point& p, double* derivparam)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -2298,6 +2298,21 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
|
|||
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");
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d,%d)) ",
|
||||
|
|
Loading…
Reference in New Issue
Block a user