Solver InternalAlignment: Change to diameters instead of radii to be able to draw asymptotes
GCS and Sketch.cpp support
This commit is contained in:
parent
4fce95a7da
commit
fb12cb83fc
|
@ -63,7 +63,10 @@ enum InternalAlignmentType {
|
|||
EllipseMajorDiameter = 1,
|
||||
EllipseMinorDiameter = 2,
|
||||
EllipseFocus1 = 3,
|
||||
EllipseFocus2 = 4
|
||||
EllipseFocus2 = 4,
|
||||
HyperbolaMajor = 5,
|
||||
HyperbolaMinor = 6,
|
||||
HyperbolaFocus = 7
|
||||
};
|
||||
|
||||
/// define if you want to use the end or start point
|
||||
|
|
|
@ -991,6 +991,15 @@ int Sketch::addConstraint(const Constraint *constraint)
|
|||
case EllipseFocus2:
|
||||
rtn = addInternalAlignmentEllipseFocus2(constraint->First,constraint->Second);
|
||||
break;
|
||||
case HyperbolaMajor:
|
||||
rtn = addInternalAlignmentHyperbolaMajorDiameter(constraint->First,constraint->Second);
|
||||
break;
|
||||
case HyperbolaMinor:
|
||||
rtn = addInternalAlignmentHyperbolaMinorDiameter(constraint->First,constraint->Second);
|
||||
break;
|
||||
case HyperbolaFocus:
|
||||
rtn = addInternalAlignmentHyperbolaFocus(constraint->First,constraint->Second);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1944,26 +1953,26 @@ int Sketch::addInternalAlignmentEllipseMajorDiameter(int geoId1, int geoId2)
|
|||
int Sketch::addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
|
||||
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Line)
|
||||
return -1;
|
||||
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
int pointId2 = getPointId(geoId2, end);
|
||||
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size()) &&
|
||||
pointId2 >= 0 && pointId2 < int(Points.size())) {
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
GCS::Point &p2 = Points[pointId2];
|
||||
|
||||
|
||||
if(Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
|
||||
|
||||
// constraints
|
||||
// 1. start point with ellipse -a
|
||||
// 2. end point with ellipse +a
|
||||
|
@ -1973,7 +1982,7 @@ int Sketch::addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2)
|
|||
}
|
||||
else {
|
||||
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
|
||||
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseMinorDiameter(a1, p1, p2, tag);
|
||||
return ConstraintsCounter;
|
||||
|
@ -1985,23 +1994,23 @@ int Sketch::addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2)
|
|||
int Sketch::addInternalAlignmentEllipseFocus1(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
|
||||
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Point)
|
||||
return -1;
|
||||
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size())) {
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
|
||||
|
||||
if(Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
|
||||
|
||||
// constraints
|
||||
// 1. start point with ellipse -a
|
||||
// 2. end point with ellipse +a
|
||||
|
@ -2011,7 +2020,7 @@ int Sketch::addInternalAlignmentEllipseFocus1(int geoId1, int geoId2)
|
|||
}
|
||||
else {
|
||||
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
|
||||
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseFocus1(a1, p1, tag);
|
||||
return ConstraintsCounter;
|
||||
|
@ -2059,6 +2068,95 @@ int Sketch::addInternalAlignmentEllipseFocus2(int geoId1, int geoId2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int Sketch::addInternalAlignmentHyperbolaMajorDiameter(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type != ArcOfHyperbola)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Line)
|
||||
return -1;
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
int pointId2 = getPointId(geoId2, end);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size()) &&
|
||||
pointId2 >= 0 && pointId2 < int(Points.size())) {
|
||||
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
GCS::Point &p2 = Points[pointId2];
|
||||
|
||||
GCS::ArcOfHyperbola &a1 = ArcsOfHyperbola[Geoms[geoId1].index];
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentHyperbolaMajorDiameter(a1, p1, p2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Sketch::addInternalAlignmentHyperbolaMinorDiameter(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type != ArcOfHyperbola)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Line)
|
||||
return -1;
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
int pointId2 = getPointId(geoId2, end);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size()) &&
|
||||
pointId2 >= 0 && pointId2 < int(Points.size())) {
|
||||
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
GCS::Point &p2 = Points[pointId2];
|
||||
|
||||
GCS::ArcOfHyperbola &a1 = ArcsOfHyperbola[Geoms[geoId1].index];
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentHyperbolaMinorDiameter(a1, p1, p2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Sketch::addInternalAlignmentHyperbolaFocus(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type != ArcOfHyperbola)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Point)
|
||||
return -1;
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size())) {
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
|
||||
GCS::ArcOfHyperbola &a1 = ArcsOfHyperbola[Geoms[geoId1].index];
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentHyperbolaFocus(a1, p1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
double Sketch::calculateAngleViaPoint(int geoId1, int geoId2, double px, double py)
|
||||
{
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
|
|
|
@ -305,6 +305,10 @@ public:
|
|||
int addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2);
|
||||
int addInternalAlignmentEllipseFocus1(int geoId1, int geoId2);
|
||||
int addInternalAlignmentEllipseFocus2(int geoId1, int geoId2);
|
||||
/// add InternalAlignmentHyperbolaMajorRadius to a line and a hyperbola
|
||||
int addInternalAlignmentHyperbolaMajorDiameter(int geoId1, int geoId2);
|
||||
int addInternalAlignmentHyperbolaMinorDiameter(int geoId1, int geoId2);
|
||||
int addInternalAlignmentHyperbolaFocus(int geoId1, int geoId2);
|
||||
//@}
|
||||
public:
|
||||
//This func is to be used during angle-via-point constraint creation. It calculates
|
||||
|
|
|
@ -1300,21 +1300,35 @@ void ConstraintInternalAlignmentPoint2Hyperbola::errorgrad(double *err, double *
|
|||
DeriVector2 poa;//point to align to
|
||||
bool by_y_not_by_x = false;//a flag to indicate if the alignment error function is for y (false - x, true - y).
|
||||
|
||||
poa = c.sum(emaj.multD(a, da));
|
||||
|
||||
switch(AlignmentType){
|
||||
case HyperbolaPositiveMajorX:
|
||||
case HyperbolaPositiveMajorY:
|
||||
poa = c.sum(emaj.multD(a, da));
|
||||
by_y_not_by_x = AlignmentType == HyperbolaPositiveMajorY;
|
||||
break;
|
||||
case HyperbolaNegativeMajorX:
|
||||
case HyperbolaNegativeMajorY:
|
||||
poa = c.sum(emaj.multD(-a, -da));
|
||||
by_y_not_by_x = AlignmentType == HyperbolaNegativeMajorY;
|
||||
break;
|
||||
case HyperbolaPositiveMinorX:
|
||||
case HyperbolaPositiveMinorY:
|
||||
{
|
||||
DeriVector2 A(poa.x,poa.y);
|
||||
DeriVector2 pa = c.sum(emaj.multD(a, da));
|
||||
DeriVector2 A(pa.x,pa.y);
|
||||
poa = A.sum(emin.multD(b, db));
|
||||
by_y_not_by_x = AlignmentType == HyperbolaPositiveMinorY;
|
||||
break;
|
||||
}
|
||||
case HyperbolaNegativeMinorX:
|
||||
case HyperbolaNegativeMinorY:
|
||||
{
|
||||
DeriVector2 pa = c.sum(emaj.multD(a, da));
|
||||
DeriVector2 A(pa.x,pa.y);
|
||||
poa = A.sum(emin.multD(-b, -db));
|
||||
by_y_not_by_x = AlignmentType == HyperbolaNegativeMinorY;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
//shouldn't happen
|
||||
poa = pv;//align to the point itself, doing nothing essentially
|
||||
|
|
|
@ -81,8 +81,12 @@ namespace GCS
|
|||
EllipseFocus2Y = 9,
|
||||
HyperbolaPositiveMajorX = 10,
|
||||
HyperbolaPositiveMajorY = 11,
|
||||
HyperbolaPositiveMinorX = 12,
|
||||
HyperbolaPositiveMinorY = 13
|
||||
HyperbolaNegativeMajorX = 12,
|
||||
HyperbolaNegativeMajorY = 13,
|
||||
HyperbolaPositiveMinorX = 14,
|
||||
HyperbolaPositiveMinorY = 15,
|
||||
HyperbolaNegativeMinorX = 16,
|
||||
HyperbolaNegativeMinorY = 17
|
||||
};
|
||||
|
||||
class Constraint
|
||||
|
|
|
@ -793,6 +793,13 @@ int System::addConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, I
|
|||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentPoint2Hyperbola(Hyperbola &e, Point &p1, InternalAlignmentType alignmentType, int tagId)
|
||||
{
|
||||
Constraint *constr = new ConstraintInternalAlignmentPoint2Hyperbola(e, p1, alignmentType);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
double X_1=*p1.x;
|
||||
|
@ -883,6 +890,97 @@ int System::addConstraintInternalAlignmentEllipseFocus2(Ellipse &e, Point &p1, i
|
|||
return addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseFocus2Y,tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentHyperbolaMajorDiameter(Hyperbola &e, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
double X_1=*p1.x;
|
||||
double Y_1=*p1.y;
|
||||
double X_2=*p2.x;
|
||||
double Y_2=*p2.y;
|
||||
double X_c=*e.center.x;
|
||||
double Y_c=*e.center.y;
|
||||
double X_F1=*e.focus1.x;
|
||||
double Y_F1=*e.focus1.y;
|
||||
double b=*e.radmin;
|
||||
|
||||
// P1=vector([X_1,Y_1])
|
||||
// P2=vector([X_2,Y_2])
|
||||
// dF1= (F1-C)/sqrt((F1-C)*(F1-C))
|
||||
// print "these are the extreme points of the major axis"
|
||||
// PA = C + a * dF1
|
||||
// PN = C - a * dF1
|
||||
// print "this is a simple function to know which point is closer to the positive edge of the ellipse"
|
||||
// DMC=(P1-PA)*(P1-PA)-(P2-PA)*(P2-PA)
|
||||
double closertopositivemajor= pow(-X_1 + X_c + (X_F1 - X_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2)
|
||||
+ pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2)
|
||||
- pow(-X_2 + X_c + (X_F1 - X_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) +
|
||||
pow(-Y_1 + Y_c + (Y_F1 - Y_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) -
|
||||
pow(-Y_2 + Y_c + (Y_F1 - Y_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2);
|
||||
|
||||
if(closertopositivemajor>0){
|
||||
//p2 is closer to positivemajor. Assign constraints back-to-front.
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaPositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaPositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaNegativeMajorY,tagId);
|
||||
}
|
||||
else{
|
||||
//p1 is closer to positivemajor
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaPositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaPositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaNegativeMajorY,tagId);
|
||||
}
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentHyperbolaMinorDiameter(Hyperbola &e, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
double X_1=*p1.x;
|
||||
double Y_1=*p1.y;
|
||||
double X_2=*p2.x;
|
||||
double Y_2=*p2.y;
|
||||
double X_c=*e.center.x;
|
||||
double Y_c=*e.center.y;
|
||||
double X_F1=*e.focus1.x;
|
||||
double Y_F1=*e.focus1.y;
|
||||
double b=*e.radmin;
|
||||
|
||||
// Same idea as for major above, but for minor
|
||||
// DMC=(P1-PA)*(P1-PA)-(P2-PA)*(P2-PA)
|
||||
double closertopositiveminor= pow(-X_1 + X_c + b*(Y_F1 - Y_c)/sqrt(pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2)) + (X_F1 - X_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) -
|
||||
pow(-X_2 + X_c + b*(Y_F1 - Y_c)/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 -
|
||||
Y_c, 2)) + (X_F1 - X_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 -
|
||||
Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) + pow(-Y_1 +
|
||||
Y_c - b*(X_F1 - X_c)/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) +
|
||||
(Y_F1 - Y_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c,
|
||||
2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) - pow(-Y_2 + Y_c -
|
||||
b*(X_F1 - X_c)/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) + (Y_F1 -
|
||||
Y_c)*(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c,
|
||||
2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2);
|
||||
|
||||
if(closertopositiveminor>0){
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaPositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaPositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaNegativeMinorY,tagId);
|
||||
} else {
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaPositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p1,HyperbolaPositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Hyperbola(e,p2,HyperbolaNegativeMinorY,tagId);
|
||||
}
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentHyperbolaFocus(Hyperbola &e, Point &p1, int tagId)
|
||||
{
|
||||
addConstraintEqual(e.focus1.x, p1.x, tagId);
|
||||
return addConstraintEqual(e.focus1.y, p1.y, tagId);
|
||||
}
|
||||
|
||||
|
||||
//calculates angle between two curves at point of their intersection p. If two
|
||||
//points are supplied, p is used for first curve and p2 for second, yielding a
|
||||
|
|
|
@ -225,6 +225,10 @@ namespace GCS
|
|||
int addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseFocus1(Ellipse &e, Point &p1, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseFocus2(Ellipse &e, Point &p1, int tagId=0);
|
||||
int addConstraintInternalAlignmentPoint2Hyperbola(Hyperbola &e, Point &p1, InternalAlignmentType alignmentType, int tagId=0);
|
||||
int addConstraintInternalAlignmentHyperbolaMajorDiameter(Hyperbola &e, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintInternalAlignmentHyperbolaMinorDiameter(Hyperbola &e, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintInternalAlignmentHyperbolaFocus(Hyperbola &e, Point &p1, int tagId=0);
|
||||
|
||||
double calculateAngleViaPoint(Curve &crv1, Curve &crv2, Point &p);
|
||||
double calculateAngleViaPoint(Curve &crv1, Curve &crv2, Point &p1, Point &p2);
|
||||
|
|
Loading…
Reference in New Issue
Block a user