1 # Copyright (C) 2019-2023 CEA, EDF
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 Test constraint "Tangent" applied to ellipse and another entity
27 from salome.shaper import model
30 from SketchAPI import *
32 __updated__ = "2019-09-20"
34 class TestTangentEllipse(unittest.TestCase):
36 axisStart = GeomAPI_Pnt2d(20., 60.)
37 axisEnd = GeomAPI_Pnt2d(80., 50.)
38 passedPoint = GeomAPI_Pnt2d(60., 70.)
41 self.myDocument = model.moduleDocument()
42 self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
43 macroEllipse = self.mySketch.addEllipse(axisStart, axisEnd, passedPoint, False)
45 self.myEllipse = SketchAPI_Ellipse(model.lastSubFeature(self.mySketch, "SketchEllipse"))
46 self.myCenter = macroEllipse.center()
47 self.myFocus1 = macroEllipse.focus1()
48 self.myFocus2 = macroEllipse.focus2()
49 self.myMajorAxis = macroEllipse.majorAxis()
50 self.myMajorStart = macroEllipse.majorAxisStart()
51 self.myMajorEnd = macroEllipse.majorAxisEnd()
52 self.myMinorAxis = macroEllipse.minorAxis()
53 self.myMinorStart = macroEllipse.minorAxisStart()
54 self.myMinorEnd = macroEllipse.minorAxisEnd()
62 self.myNbInternals = 11
63 self.myNbCoincidence = 0
69 self.assertPoints(self.myCenter.coordinates(), self.myEllipse.center())
70 self.assertPoints(self.myFocus1.coordinates(), self.myEllipse.firstFocus())
71 self.assertPoints(self.myFocus2.coordinates(), self.myEllipse.secondFocus())
72 self.assertPoints(self.myMajorStart.coordinates(), self.myEllipse.majorAxisNegative())
73 self.assertPoints(self.myMajorEnd.coordinates(), self.myEllipse.majorAxisPositive())
74 self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipse.majorAxisNegative())
75 self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipse.majorAxisPositive())
76 self.assertPoints(self.myMinorStart.coordinates(), self.myEllipse.minorAxisNegative())
77 self.assertPoints(self.myMinorEnd.coordinates(), self.myEllipse.minorAxisPositive())
78 self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipse.minorAxisNegative())
79 self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipse.minorAxisPositive())
80 model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
81 model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
82 model.testNbSubFeatures(self.mySketch, "SketchArc", self.myNbArcs)
83 model.testNbSubFeatures(self.mySketch, "SketchCircle", self.myNbCircles)
84 model.testNbSubFeatures(self.mySketch, "SketchEllipse", self.myNbEllipses)
85 model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", self.myNbInternals)
86 model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", self.myNbCoincidence)
87 model.testNbSubFeatures(self.mySketch, "SketchConstraintTangent", self.myNbTangency)
91 self.assertEqual(model.dof(self.mySketch), self.myDOF)
93 def assertTangentLineEllipse(self, theLine, theEllipse):
94 aLine = GeomAPI_Lin2d(theLine.startPoint().pnt(), theLine.endPoint().pnt())
95 projF1 = aLine.project(theEllipse.firstFocus().pnt())
96 projF2 = aLine.project(theEllipse.secondFocus().pnt())
98 distF1P1 = model.distancePointPoint(theEllipse.firstFocus(), projF1)
99 distF2P2 = model.distancePointPoint(theEllipse.secondFocus(), projF2)
101 tgPoint = GeomAPI_Pnt2d((projF1.x() * distF2P2 + projF2.x() * distF1P1) / (distF1P1 + distF2P2), (projF1.y() * distF2P2 + projF2.y() * distF1P1) / (distF1P1 + distF2P2))
102 distF1T = model.distancePointPoint(theEllipse.firstFocus(), tgPoint)
103 distF2T = model.distancePointPoint(theEllipse.secondFocus(), tgPoint)
104 self.assertAlmostEqual(distF1T + distF2T, 2 * theEllipse.majorRadius().value())
106 def assertTangentCircleEllipse(self, theCircle, theEllipse):
107 axis = GeomAPI_Dir2d(theEllipse.firstFocus().x() - theEllipse.center().x(), theEllipse.firstFocus().y() - theEllipse.center().y())
108 anEllipse = GeomAPI_Ellipse2d(theEllipse.center().pnt(), axis, theEllipse.majorRadius().value(), theEllipse.minorRadius().value())
109 aCircle = GeomAPI_Circ2d(theCircle.center().pnt(), GeomAPI_Dir2d(1, 0), theCircle.radius().value())
111 pOnE = GeomAPI_Pnt2d(0, 0)
112 pOnC = GeomAPI_Pnt2d(0, 0)
113 anEllipse.distance(aCircle, pOnE, pOnC)
114 self.assertAlmostEqual(model.distancePointPoint(pOnE, theCircle.center()), theCircle.radius().value())
116 dist1 = model.distancePointPoint(pOnC, theEllipse.firstFocus())
117 dist2 = model.distancePointPoint(pOnC, theEllipse.secondFocus())
118 self.assertAlmostEqual(dist1 + dist2, 2 * theEllipse.majorRadius().value())
120 def assertTangentEllipses(self, theEllipse1, theEllipse2):
121 axis1 = GeomAPI_Dir2d(theEllipse1.firstFocus().x() - theEllipse1.center().x(), theEllipse1.firstFocus().y() - theEllipse1.center().y())
122 anEllipse1 = GeomAPI_Ellipse2d(theEllipse1.center().pnt(), axis1, theEllipse1.majorRadius().value(), theEllipse1.minorRadius().value())
123 axis2 = GeomAPI_Dir2d(theEllipse2.firstFocus().x() - theEllipse2.center().x(), theEllipse2.firstFocus().y() - theEllipse2.center().y())
124 anEllipse2 = GeomAPI_Ellipse2d(theEllipse2.center().pnt(), axis2, theEllipse2.majorRadius().value(), theEllipse2.minorRadius().value())
126 p1 = GeomAPI_Pnt2d(0, 0)
127 p2 = GeomAPI_Pnt2d(0, 0)
128 anEllipse1.distance(anEllipse2, p1, p2)
130 dist1 = model.distancePointPoint(p2, theEllipse1.firstFocus())
131 dist2 = model.distancePointPoint(p2, theEllipse1.secondFocus())
132 self.assertAlmostEqual(dist1 + dist2, 2 * theEllipse1.majorRadius().value())
134 dist1 = model.distancePointPoint(p1, theEllipse2.firstFocus())
135 dist2 = model.distancePointPoint(p1, theEllipse2.secondFocus())
136 self.assertAlmostEqual(dist1 + dist2, 2 * theEllipse2.majorRadius().value())
138 def assertPoints(self, thePoint1, thePoint2):
139 self.assertAlmostEqual(thePoint1.x(), thePoint2.x())
140 self.assertAlmostEqual(thePoint1.y(), thePoint2.y())
143 def test_line_tangent(self):
144 """ Test 1. Set tangency between ellipse and a line
146 aLine = self.mySketch.addLine(10, 10, 90, 40)
151 self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
152 self.myNbTangency += 1
156 self.assertTangentLineEllipse(aLine, self.myEllipse)
159 def test_line_coincident_then_tangent(self):
160 """ Test 2. Set tangency between ellipse and a line, if the extremity of the line is coincident with the ellipse
162 aLine = self.mySketch.addLine(10, 10, 90, 40)
163 self.mySketch.setCoincident(aLine.endPoint(), self.myEllipse.result())
165 self.myNbCoincidence += 1
169 self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
170 self.myNbTangency += 1
174 self.assertTangentLineEllipse(aLine, self.myEllipse)
177 def test_line_tangent_then_coincident(self):
178 """ Test 3. Set tangency between ellipse and a line, after that apply coincidence of extremity of the line and the ellipse's curve
180 aLine = self.mySketch.addLine(10, 10, 90, 40)
185 self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
186 self.myNbTangency += 1
190 self.mySketch.setCoincident(aLine.startPoint(), self.myEllipse.result())
191 self.myNbCoincidence += 1
195 self.assertTangentLineEllipse(aLine, self.myEllipse)
198 def test_line_tangent_then_remove_coincidence(self):
199 """ Test 4. Set tangency between ellipse and a line, which have a coincident point, then remove this coincidence
201 aLine = self.mySketch.addLine(10, 10, 90, 40)
202 aCoincidence = self.mySketch.setCoincident(aLine.endPoint(), self.myEllipse.result())
204 self.myNbCoincidence += 1
208 self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
209 self.myNbTangency += 1
213 self.myDocument.removeFeature(aCoincidence.feature())
214 self.myNbCoincidence -= 1
218 self.assertTangentLineEllipse(aLine, self.myEllipse)
221 def test_circle_tangent(self):
222 """ Test 5. Set tangency between ellipse and a circle
224 aCircle = self.mySketch.addCircle(30, 10, 20)
225 self.myNbCircles += 1
229 self.mySketch.setTangent(self.myEllipse.result(), aCircle.defaultResult())
230 self.myNbTangency += 1
234 self.assertTangentCircleEllipse(aCircle, self.myEllipse)
237 def test_circle_coincident_then_tangent(self):
238 """ Test 6. Set tangency between ellipse and a circle, if the circle is coincident with start point of ellipse's minor axis
240 aCircle = self.mySketch.addCircle(30, 10, 20)
241 self.mySketch.setCoincident(self.myMinorStart.coordinates(), aCircle.defaultResult())
242 self.myNbCircles += 1
243 self.myNbCoincidence += 1
247 self.mySketch.setTangent(self.myEllipse.result(), aCircle.defaultResult())
248 self.myNbTangency += 1
252 self.assertTangentCircleEllipse(aCircle, self.myEllipse)
253 self.assertAlmostEqual(model.distancePointPoint(aCircle.center(), self.myMinorStart.coordinates()), aCircle.radius().value())
256 def test_arc_tangent(self):
257 """ Test 7. Set tangency between ellipse and a circular arc
259 anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
264 self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
265 self.myNbTangency += 1
269 self.assertTangentCircleEllipse(anArc, self.myEllipse)
272 def test_arc_coincident_then_tangent(self):
273 """ Test 8. Set tangency between ellipse and an arc, if the extremity of the arc is coincident with the ellipse
275 anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
276 self.mySketch.setCoincident(anArc.endPoint(), self.myEllipse.result())
278 self.myNbCoincidence += 1
282 self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
283 self.myNbTangency += 1
287 self.assertTangentCircleEllipse(anArc, self.myEllipse)
290 def test_arc_tangent_then_coincident(self):
291 """ Test 9. Set tangency between ellipse and an arc, after that apply coincidence of extremity of the arc and the ellipse's curve
293 anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
298 self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
299 self.myNbTangency += 1
303 self.mySketch.setCoincident(anArc.startPoint(), self.myEllipse.result())
304 self.myNbCoincidence += 1
308 self.assertTangentCircleEllipse(anArc, self.myEllipse)
311 def test_arc_tangent_then_remove_coincidence(self):
312 """ Test 10. Set tangency between ellipse and an arc, which have a coincident point, then remove this coincidence
314 anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
315 aCoincidence = self.mySketch.setCoincident(anArc.endPoint(), self.myEllipse.result())
317 self.myNbCoincidence += 1
321 self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
322 self.myNbTangency += 1
326 self.myDocument.removeFeature(aCoincidence.feature())
327 self.myNbCoincidence -= 1
331 self.assertTangentCircleEllipse(anArc, self.myEllipse)
334 def test_ellipse_tangent(self):
335 """ Test 11. Set tangency between two ellipses
337 anEllipse = self.mySketch.addEllipse(10, 10, 20, -50, 20)
338 self.myNbEllipses += 1
342 self.mySketch.setTangent(self.myEllipse.result(), anEllipse.result())
343 self.myNbTangency += 1
347 self.assertTangentEllipses(anEllipse, self.myEllipse)
351 if __name__ == "__main__":
352 test_program = unittest.main(exit=False)
353 assert test_program.result.wasSuccessful(), "Test failed"
354 assert model.checkPythonDump()