MCPcopy Create free account
hub / github.com/FreeCAD/FreeCAD / angle

Method angle

src/Mod/Measure/App/Measurement.cpp:669–780  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

667}
668
669double Measurement::angle(const Base::Vector3d& /*param*/) const
670{
671 // TODO: do these references arrive as obj+sub pairs or as a struct of obj + [subs]?
672 const std::vector<App::DocumentObject*>& objects = References3D.getValues();
673 const std::vector<std::string>& subElements = References3D.getSubValues();
674 int numRefs = objects.size();
675 if (numRefs == 0) {
676 throw Base::RuntimeError("No references available for angle measurement");
677 }
678 else if (measureType == MeasureType::Invalid) {
679 throw Base::RuntimeError("MeasureType is Invalid for angle measurement");
680 }
681 else if (measureType == MeasureType::TwoLines) {
682 // Only case that is supported is edge to edge
683 // The angle between two skew lines is measured by the angle between one line (A)
684 // and a line (B) with the direction of the second through a point on the first line.
685 // Since we don't know if the directions of the lines point in the same general direction
686 // we could get the angle we want or the supplementary angle.
687 if (numRefs == 2) {
688 TopoDS_Shape shape1 = getShape(objects.at(0), subElements.at(0).c_str(), TopAbs_EDGE);
689 TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(1).c_str(), TopAbs_EDGE);
690
691 BRepAdaptor_Curve curve1(TopoDS::Edge(shape1));
692 BRepAdaptor_Curve curve2(TopoDS::Edge(shape2));
693
694 if (curve1.GetType() == GeomAbs_Line && curve2.GetType() == GeomAbs_Line) {
695
696 gp_Pnt pnt1First = curve1.Value(curve1.FirstParameter());
697 gp_Dir dir1 = curve1.Line().Direction();
698 gp_Dir dir2 = curve2.Line().Direction();
699 gp_Dir dir2r = curve2.Line().Direction().Reversed();
700
701 gp_Lin l1 = gp_Lin(pnt1First, dir1); // (A)
702 gp_Lin l2 = gp_Lin(pnt1First, dir2); // (B)
703 gp_Lin l2r = gp_Lin(pnt1First, dir2r); // (B')
704 Standard_Real aRad = l1.Angle(l2);
705 double aRadr = l1.Angle(l2r);
706 return Base::toDegrees<double>(std::min(aRad, aRadr));
707 }
708 else {
709 throw Base::RuntimeError("Measurement references must both be lines");
710 }
711 }
712 else {
713 throw Base::RuntimeError("Can not compute angle measurement - too many references");
714 }
715 }
716 else if (measureType == MeasureType::Points) {
717 // NOTE: we are calculating the 3d angle here, not the projected angle
718 // ASSUMPTION: the references are in end-apex-end order
719 if (numRefs == 3) {
720 TopoDS_Shape shape0 = getShape(objects.at(0), subElements.at(0).c_str(), TopAbs_VERTEX);
721 TopoDS_Shape shape1 = getShape(objects.at(1), subElements.at(1).c_str(), TopAbs_VERTEX);
722 TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(2).c_str(), TopAbs_VERTEX);
723 if (shape0.ShapeType() != TopAbs_VERTEX || shape1.ShapeType() != TopAbs_VERTEX
724 || shape2.ShapeType() != TopAbs_VERTEX) {
725 throw Base::RuntimeError("Measurement references for 3 point angle are not Vertex");
726 }

Callers 15

getDeviationMethod · 0.45
addTextFunction · 0.45
getArcDataFunction · 0.45
_get_path_circ_ellipseFunction · 0.45
get_textFunction · 0.45
_svg_dimensionFunction · 0.45
get_svgFunction · 0.45
measure_two_obj_anglesFunction · 0.45
orientEdgeFunction · 0.45
findDistanceFunction · 0.45
getRotationFunction · 0.45
isClockwiseFunction · 0.45

Calls 15

getShapeFunction · 0.85
minFunction · 0.85
fmodFunction · 0.85
getSubValuesMethod · 0.80
atMethod · 0.80
FirstParameterMethod · 0.80
XYZMethod · 0.80
AxisMethod · 0.80
EdgeClass · 0.50
gp_LinClass · 0.50
VertexClass · 0.50
gp_DirClass · 0.50

Tested by 1