Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / GeomAPI / GeomAPI_Lin.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <GeomAPI_Lin.h>
22 #include <GeomAPI_Pnt.h>
23 #include <GeomAPI_Dir.h>
24
25 #include <gp_Dir.hxx>
26 #include <gp_Lin.hxx>
27 #include <gp_Lin2d.hxx>
28 #include <gp_Pln.hxx>
29 #include <gp_Pnt.hxx>
30 #include <gp_XYZ.hxx>
31
32 #include <ElSLib.hxx>
33 #include <IntAna2d_AnaIntersection.hxx>
34 #include <Precision.hxx>
35 #include <ProjLib.hxx>
36
37 #define MY_LIN implPtr<gp_Lin>()
38
39 static gp_Lin* newLine(const double theStartX, const double theStartY, const double theStartZ,
40                        const double theEndX, const double theEndY, const double theEndZ)
41 {
42   gp_XYZ aDir(theEndX - theStartX, theEndY - theStartY, theEndZ - theStartZ);
43   gp_Pnt aStart(theStartX, theStartY, theStartZ);
44   return new gp_Lin(aStart, gp_Dir(aDir));
45 }
46
47 GeomAPI_Lin::GeomAPI_Lin(const double theStartX, const double theStartY, const double theStartZ,
48                          const double theEndX, const double theEndY, const double theEndZ)
49     : GeomAPI_Interface(newLine(theStartX, theStartY, theStartZ, theEndX, theEndY, theEndZ))
50 {
51 }
52
53 GeomAPI_Lin::GeomAPI_Lin(const std::shared_ptr<GeomAPI_Pnt>& theStart,
54                          const std::shared_ptr<GeomAPI_Pnt>& theEnd)
55     : GeomAPI_Interface(
56         newLine(theStart->x(), theStart->y(), theStart->z(), theEnd->x(), theEnd->y(), theEnd->z()))
57 {
58 }
59
60 GeomAPI_Lin::GeomAPI_Lin(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
61                          const std::shared_ptr<GeomAPI_Dir>& theDirection)
62     : GeomAPI_Interface(newLine(theOrigin->x(), theOrigin->y(), theOrigin->z(),
63                                 theOrigin->x() + theDirection->x(),
64                                 theOrigin->y() + theDirection->y(),
65                                 theOrigin->z() + theDirection->z()))
66 {
67 }
68
69 std::shared_ptr<GeomAPI_Pnt> GeomAPI_Lin::location()
70 {
71   gp_Pnt aLoc = impl<gp_Lin>().Location();
72   return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
73 }
74
75 std::shared_ptr<GeomAPI_Dir> GeomAPI_Lin::direction()
76 {
77   const gp_Dir& aDir = impl<gp_Lin>().Direction();
78   return std::shared_ptr<GeomAPI_Dir>(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()));
79 }
80
81 double GeomAPI_Lin::distance(const std::shared_ptr<GeomAPI_Pnt>& thePoint) const
82 {
83   return MY_LIN->Distance(thePoint->impl<gp_Pnt>());
84 }
85
86 const std::shared_ptr<GeomAPI_Pnt> GeomAPI_Lin::intersect(
87     const std::shared_ptr<GeomAPI_Lin>& theLine) const
88 {
89   if (MY_LIN->SquareDistance(theLine->impl<gp_Lin>()) > Precision::Confusion())
90   return std::shared_ptr<GeomAPI_Pnt>();
91
92   const gp_Dir& aDir1 = MY_LIN->Direction();
93   const gp_Dir& aDir2 = theLine->impl<gp_Lin>().Direction();
94   gp_Dir aCross = aDir1.Crossed(aDir2);
95   gp_Pln aPlane(MY_LIN->Location(), aCross);  // plane containing both lines
96
97   gp_Lin2d aPrjLine1 = ProjLib::Project(aPlane, *MY_LIN);
98   gp_Lin2d aPrjLine2 = ProjLib::Project(aPlane, theLine->impl<gp_Lin>());
99
100   IntAna2d_AnaIntersection anInter(aPrjLine1, aPrjLine2);
101   if (!anInter.IsDone() || anInter.IsEmpty())
102   return std::shared_ptr<GeomAPI_Pnt>();
103   const gp_Pnt2d& anIntPnt2d = anInter.Point(1).Value();
104   gp_Pnt aResult = ElSLib::Value(anIntPnt2d.X(), anIntPnt2d.Y(), aPlane);
105
106   return std::shared_ptr<GeomAPI_Pnt>(
107   new GeomAPI_Pnt(aResult.X(), aResult.Y(), aResult.Z()));
108 }
109
110 const std::shared_ptr<GeomAPI_Pnt> GeomAPI_Lin::project(
111     const std::shared_ptr<GeomAPI_Pnt>& thePoint) const
112 {
113   const gp_XYZ& aDir = MY_LIN->Direction().XYZ();
114   const gp_XYZ& aLoc = MY_LIN->Location().XYZ();
115   const gp_XYZ& aPnt = thePoint->impl<gp_Pnt>().XYZ();
116   double aParam = aDir.Dot(aPnt - aLoc);
117
118   gp_XYZ aResult = aLoc + aDir * aParam;
119   return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aResult.X(), aResult.Y(), aResult.Z()));
120 }
121
122 bool GeomAPI_Lin::contains(const std::shared_ptr<GeomAPI_Pnt> thePoint,
123                            const double theLinearTolerance) const
124 {
125   if(!thePoint.get()) {
126     return false;
127   }
128
129   return MY_LIN->Contains(thePoint->impl<gp_Pnt>(), theLinearTolerance) == Standard_True;
130 }
131
132 bool GeomAPI_Lin::isParallel(const std::shared_ptr<GeomAPI_Lin> theLin) const
133 {
134   return MY_LIN->Direction().IsParallel(theLin->impl<gp_Lin>().Direction(),
135                                         Precision::Confusion()) == Standard_True;
136 }
137
138 bool GeomAPI_Lin::isCoplanar(const std::shared_ptr<GeomAPI_Lin> theLin) const
139 {
140   if(MY_LIN->SquareDistance(theLin->impl<gp_Lin>()) > Precision::Confusion()) {
141     return false;
142   }
143
144   return true;
145 }