const double tolerance = 1.e-7;
#define PI 3.1415926535897932
+/// \brief Calculate intersection point of two lines
+static std::shared_ptr<GeomAPI_Pnt2d> intersect(FeaturePtr theLine1, FeaturePtr theLine2);
+
SketchPlugin_ConstraintAngle::SketchPlugin_ConstraintAngle()
{
// coordinates are calculated according to the center of shapes intersection
std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+
+ std::shared_ptr<ModelAPI_Data> aData = data();
+ std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
+ FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
+ FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
+
+ // Intersection of lines
+ std::shared_ptr<GeomAPI_Pnt2d> anInter = intersect(aLineA, aLineB);
+ if (!anInter)
+ return;
+
+ myFlyoutUpdate = true;
+ std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutAttr->pnt()->xy()->decreased(anInter->xy());
+ if (aFlyoutDir->dot(aFlyoutDir) < tolerance * tolerance)
+ aFlyoutAttr->setValue(aFlyoutAttr->x() + tolerance, aFlyoutAttr->y());
+ myFlyoutUpdate = false;
}
}
FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
+ // Intersection of lines
+ std::shared_ptr<GeomAPI_Pnt2d> anInter = intersect(aLineA, aLineB);
+ if (!anInter)
+ return anAngle;
+
// Start and end points of lines
std::shared_ptr<GeomDataAPI_Point2D> aPointA1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aLineA->attribute(SketchPlugin_Line::START_ID()));
std::shared_ptr<GeomAPI_Pnt2d> aEndA = aPointA2->pnt();
std::shared_ptr<GeomAPI_Pnt2d> aStartB = aPointB1->pnt();
std::shared_ptr<GeomAPI_Pnt2d> aEndB = aPointB2->pnt();
- if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance)
- return anAngle;
- // Lines and their intersection point
- std::shared_ptr<GeomAPI_Lin2d> aLA(new GeomAPI_Lin2d(aStartA, aEndA));
- std::shared_ptr<GeomAPI_Lin2d> aLB(new GeomAPI_Lin2d(aStartB, aEndB));
- std::shared_ptr<GeomAPI_Pnt2d> anInter = aLA->intersect(aLB);
- if (!anInter)
- return anAngle;
+ double aDist[2][2] = {
+ { anInter->distance(aStartA), anInter->distance(aEndA) },
+ { anInter->distance(aStartB), anInter->distance(aEndB) }
+ };
// Directions of lines
- if (anInter->distance(aEndA) < tolerance)
+ if (aDist[0][1] < tolerance)
aEndA = aStartA;
- if (anInter->distance(aEndB) < tolerance)
+ if (aDist[1][1] < tolerance)
aEndB = aStartB;
std::shared_ptr<GeomAPI_Dir2d> aDirA(new GeomAPI_Dir2d(aEndA->xy()->decreased(anInter->xy())));
std::shared_ptr<GeomAPI_Dir2d> aDirB(new GeomAPI_Dir2d(aEndB->xy()->decreased(anInter->xy())));
- anAngle = aDirA->angle(aDirB) * 180.0 / PI;
+ anAngle = fabs(aDirA->angle(aDirB)) * 180.0 / PI;
+
+ // If the lines intersected inside one of them, the angle selected is less than 90 degrees
+ if ((aDist[0][0] >= tolerance && aDist[0][1] >= tolerance &&
+ aDist[0][0] + aDist[0][1] < aStartA->distance(aEndA) + 2.0 * tolerance) ||
+ (aDist[1][0] >= tolerance && aDist[1][1] >= tolerance &&
+ aDist[1][0] + aDist[1][1] < aStartB->distance(aEndB) + 2.0 * tolerance)) {
+ if (anAngle > 90.0)
+ anAngle = 180.0 - anAngle;
+ }
+
return anAngle;
}
myFlyoutUpdate = false;
return true;
-}
\ No newline at end of file
+}
+
+
+// =============== Auxiliary functions ==================================
+std::shared_ptr<GeomAPI_Pnt2d> intersect(FeaturePtr theLine1, FeaturePtr theLine2)
+{
+ // Start and end points of lines
+ std::shared_ptr<GeomDataAPI_Point2D> aPointA1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theLine1->attribute(SketchPlugin_Line::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aPointA2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theLine1->attribute(SketchPlugin_Line::END_ID()));
+
+ std::shared_ptr<GeomDataAPI_Point2D> aPointB1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theLine2->attribute(SketchPlugin_Line::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aPointB2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theLine2->attribute(SketchPlugin_Line::END_ID()));
+
+ std::shared_ptr<GeomAPI_Pnt2d> aStartA = aPointA1->pnt();
+ std::shared_ptr<GeomAPI_Pnt2d> aEndA = aPointA2->pnt();
+ std::shared_ptr<GeomAPI_Pnt2d> aStartB = aPointB1->pnt();
+ std::shared_ptr<GeomAPI_Pnt2d> aEndB = aPointB2->pnt();
+ if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance)
+ std::shared_ptr<GeomAPI_Pnt2d>();
+
+ // Lines and their intersection point
+ std::shared_ptr<GeomAPI_Lin2d> aLA(new GeomAPI_Lin2d(aStartA, aEndA));
+ std::shared_ptr<GeomAPI_Lin2d> aLB(new GeomAPI_Lin2d(aStartB, aEndB));
+ return aLA->intersect(aLB);
+}