1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski #ifndef _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX
25*b1cdbd2cSJim Jagielski #define _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <basegfx/point/b3dpoint.hxx>
28*b1cdbd2cSJim Jagielski #include <basegfx/vector/b3dvector.hxx>
29*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b3dpolypolygon.hxx>
30*b1cdbd2cSJim Jagielski #include <basegfx/vector/b2enums.hxx>
31*b1cdbd2cSJim Jagielski #include <vector>
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski //////////////////////////////////////////////////////////////////////////////
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski namespace basegfx
36*b1cdbd2cSJim Jagielski {
37*b1cdbd2cSJim Jagielski 	// predefinitions
38*b1cdbd2cSJim Jagielski 	class B3DPolygon;
39*b1cdbd2cSJim Jagielski 	class B3DRange;
40*b1cdbd2cSJim Jagielski 
41*b1cdbd2cSJim Jagielski 	namespace tools
42*b1cdbd2cSJim Jagielski 	{
43*b1cdbd2cSJim Jagielski 		// B3DPolygon tools
44*b1cdbd2cSJim Jagielski 
45*b1cdbd2cSJim Jagielski 		/**	Check if given polygon is closed. This is kind of a
46*b1cdbd2cSJim Jagielski 			'classic' method to support old polygon definitions.
47*b1cdbd2cSJim Jagielski 			Those old polygon definitions define the closed state
48*b1cdbd2cSJim Jagielski 			of the polygon using identical start and endpoints. This
49*b1cdbd2cSJim Jagielski 			method corrects this (removes double start/end points)
50*b1cdbd2cSJim Jagielski 			and sets the Closed()-state of the polygon correctly.
51*b1cdbd2cSJim Jagielski 		*/
52*b1cdbd2cSJim Jagielski 		void checkClosed(B3DPolygon& rCandidate);
53*b1cdbd2cSJim Jagielski 
54*b1cdbd2cSJim Jagielski 		// Get successor and predecessor indices. Returning the same index means there
55*b1cdbd2cSJim Jagielski 		// is none. Same for successor.
56*b1cdbd2cSJim Jagielski 		sal_uInt32 getIndexOfPredecessor(sal_uInt32 nIndex, const B3DPolygon& rCandidate);
57*b1cdbd2cSJim Jagielski 		sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const B3DPolygon& rCandidate);
58*b1cdbd2cSJim Jagielski 
59*b1cdbd2cSJim Jagielski 		// Get orientation of Polygon
60*b1cdbd2cSJim Jagielski 		B2VectorOrientation getOrientation(const B3DPolygon& rCandidate);
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski 		// get size of polygon. Control vectors are included in that ranges.
63*b1cdbd2cSJim Jagielski 		B3DRange getRange(const B3DPolygon& rCandidate);
64*b1cdbd2cSJim Jagielski 
65*b1cdbd2cSJim Jagielski 		// get normal vector of polygon
66*b1cdbd2cSJim Jagielski 		B3DVector getNormal(const B3DPolygon& rCandidate);
67*b1cdbd2cSJim Jagielski 
68*b1cdbd2cSJim Jagielski 		// get normal vector of positive oriented polygon
69*b1cdbd2cSJim Jagielski 		B3DVector getPositiveOrientedNormal(const B3DPolygon& rCandidate);
70*b1cdbd2cSJim Jagielski 
71*b1cdbd2cSJim Jagielski 		// get signed area of polygon
72*b1cdbd2cSJim Jagielski 		double getSignedArea(const B3DPolygon& rCandidate);
73*b1cdbd2cSJim Jagielski 
74*b1cdbd2cSJim Jagielski 		// get area of polygon
75*b1cdbd2cSJim Jagielski 		double getArea(const B3DPolygon& rCandidate);
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski 		// get signed area of polygon
78*b1cdbd2cSJim Jagielski 		double getSignedArea(const B3DPolygon& rCandidate);
79*b1cdbd2cSJim Jagielski 
80*b1cdbd2cSJim Jagielski 		// get area of polygon
81*b1cdbd2cSJim Jagielski 		double getArea(const ::basegfx::B3DPolygon& rCandidate);
82*b1cdbd2cSJim Jagielski 
83*b1cdbd2cSJim Jagielski 		// get length of polygon edge from point nIndex to nIndex + 1
84*b1cdbd2cSJim Jagielski 		double getEdgeLength(const B3DPolygon& rCandidate, sal_uInt32 nIndex);
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski 		// get length of polygon
87*b1cdbd2cSJim Jagielski 		double getLength(const B3DPolygon& rCandidate);
88*b1cdbd2cSJim Jagielski 
89*b1cdbd2cSJim Jagielski 		// get position on polygon for absolute given distance. If
90*b1cdbd2cSJim Jagielski 		// length is given, it is assumed the correct polygon length, if 0.0 it is calculated
91*b1cdbd2cSJim Jagielski 		// using getLength(...)
92*b1cdbd2cSJim Jagielski 		B3DPoint getPositionAbsolute(const B3DPolygon& rCandidate, double fDistance, double fLength = 0.0);
93*b1cdbd2cSJim Jagielski 
94*b1cdbd2cSJim Jagielski 		// get position on polygon for relative given distance in range [0.0 .. 1.0]. If
95*b1cdbd2cSJim Jagielski 		// length is given, it is assumed the correct polygon length, if 0.0 it is calculated
96*b1cdbd2cSJim Jagielski 		// using getLength(...)
97*b1cdbd2cSJim Jagielski 		B3DPoint getPositionRelative(const B3DPolygon& rCandidate, double fDistance, double fLength = 0.0);
98*b1cdbd2cSJim Jagielski 
99*b1cdbd2cSJim Jagielski 		/** Apply given LineDashing to given polygon
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski 			For a description see applyLineDashing in b2dpolygontoos.hxx
102*b1cdbd2cSJim Jagielski 		*/
103*b1cdbd2cSJim Jagielski 		void applyLineDashing(
104*b1cdbd2cSJim Jagielski 			const B3DPolygon& rCandidate,
105*b1cdbd2cSJim Jagielski 			const ::std::vector<double>& rDotDashArray,
106*b1cdbd2cSJim Jagielski 			B3DPolyPolygon* pLineTarget,
107*b1cdbd2cSJim Jagielski             B3DPolyPolygon* pGapTarget = 0,
108*b1cdbd2cSJim Jagielski 			double fFullDashDotLen = 0.0);
109*b1cdbd2cSJim Jagielski 
110*b1cdbd2cSJim Jagielski 		/** Create/replace normals for given 3d geometry with default normals from given center to outside.
111*b1cdbd2cSJim Jagielski 			rCandidate:	the 3d geometry to change
112*b1cdbd2cSJim Jagielski 			rCenter:	the center of the 3d geometry
113*b1cdbd2cSJim Jagielski          */
114*b1cdbd2cSJim Jagielski 		B3DPolygon applyDefaultNormalsSphere( const B3DPolygon& rCandidate, const B3DPoint& rCenter);
115*b1cdbd2cSJim Jagielski 
116*b1cdbd2cSJim Jagielski 		/** invert normals for given 3d geometry.
117*b1cdbd2cSJim Jagielski          */
118*b1cdbd2cSJim Jagielski 		B3DPolygon invertNormals( const B3DPolygon& rCandidate);
119*b1cdbd2cSJim Jagielski 
120*b1cdbd2cSJim Jagielski 		/** Create/replace texture coordinates for given 3d geometry with parallel projected one
121*b1cdbd2cSJim Jagielski 			rRange: the full range of the 3d geometry
122*b1cdbd2cSJim Jagielski 			If bChangeX, x texture coordinate will be recalculated.
123*b1cdbd2cSJim Jagielski 			If bChangeY, y texture coordinate will be recalculated.
124*b1cdbd2cSJim Jagielski          */
125*b1cdbd2cSJim Jagielski 		B3DPolygon applyDefaultTextureCoordinatesParallel( const B3DPolygon& rCandidate, const B3DRange& rRange, bool bChangeX = true, bool bChangeY = true);
126*b1cdbd2cSJim Jagielski 
127*b1cdbd2cSJim Jagielski 		/** Create/replace texture coordinates for given 3d geometry with spherical one
128*b1cdbd2cSJim Jagielski 			rCenter: the centre of the used 3d geometry
129*b1cdbd2cSJim Jagielski 			If bChangeX, x texture coordinate will be recalculated.
130*b1cdbd2cSJim Jagielski 			If bChangeY, y texture coordinate will be recalculated.
131*b1cdbd2cSJim Jagielski          */
132*b1cdbd2cSJim Jagielski 		B3DPolygon applyDefaultTextureCoordinatesSphere( const B3DPolygon& rCandidate, const B3DPoint& rCenter, bool bChangeX = true, bool bChangeY = true);
133*b1cdbd2cSJim Jagielski 
134*b1cdbd2cSJim Jagielski 		// test if point is inside epsilon-range around an edge defined
135*b1cdbd2cSJim Jagielski 		// by the two given points. Can be used for HitTesting. The epsilon-range
136*b1cdbd2cSJim Jagielski 		// is defined to be the cylinder centered to the given edge, using radius
137*b1cdbd2cSJim Jagielski 		// fDistance, and the sphere around both points with radius fDistance.
138*b1cdbd2cSJim Jagielski 		bool isInEpsilonRange(const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, const B3DPoint& rTestPosition, double fDistance);
139*b1cdbd2cSJim Jagielski 
140*b1cdbd2cSJim Jagielski 		// test if point is inside epsilon-range around the given Polygon. Can be used
141*b1cdbd2cSJim Jagielski 		// for HitTesting. The epsilon-range is defined to be the cylinder centered to
142*b1cdbd2cSJim Jagielski         // the given edge, using radius fDistance, and the sphere around both points with radius fDistance.
143*b1cdbd2cSJim Jagielski 		bool isInEpsilonRange(const B3DPolygon& rCandidate, const B3DPoint& rTestPosition, double fDistance);
144*b1cdbd2cSJim Jagielski 
145*b1cdbd2cSJim Jagielski 		// isInside tests for B3DPoint and other B3DPolygon. On border is not inside as long as
146*b1cdbd2cSJim Jagielski 		// not true is given in bWithBorder flag.
147*b1cdbd2cSJim Jagielski 		bool isInside(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder = false);
148*b1cdbd2cSJim Jagielski 		bool isInside(const B3DPolygon& rCandidate, const B3DPolygon& rPolygon, bool bWithBorder = false);
149*b1cdbd2cSJim Jagielski 
150*b1cdbd2cSJim Jagielski 		// calculates if given point is on given line, taking care of the numerical epsilon
151*b1cdbd2cSJim Jagielski 		bool isPointOnLine(const B3DPoint& rStart, const B3DPoint& rEnd, const B3DPoint& rCandidate, bool bWithPoints = false);
152*b1cdbd2cSJim Jagielski 
153*b1cdbd2cSJim Jagielski         // calculates if given point is on given polygon, taking care of the numerical epsilon. Uses
154*b1cdbd2cSJim Jagielski 		// isPointOnLine internally
155*b1cdbd2cSJim Jagielski 		bool isPointOnPolygon(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithPoints = true);
156*b1cdbd2cSJim Jagielski 
157*b1cdbd2cSJim Jagielski         // helper to get a fCut position between a plane (given with normal and a point)
158*b1cdbd2cSJim Jagielski         // and a line given by start and end point
159*b1cdbd2cSJim Jagielski         bool getCutBetweenLineAndPlane(const B3DVector& rPlaneNormal, const B3DPoint& rPlanePoint, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut);
160*b1cdbd2cSJim Jagielski 
161*b1cdbd2cSJim Jagielski         // helper to get a fCut position between a 3d Polygon
162*b1cdbd2cSJim Jagielski         // and a line given by start and end point
163*b1cdbd2cSJim Jagielski         bool getCutBetweenLineAndPolygon(const B3DPolygon& rCandidate, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut);
164*b1cdbd2cSJim Jagielski 
165*b1cdbd2cSJim Jagielski 		//////////////////////////////////////////////////////////////////////
166*b1cdbd2cSJim Jagielski 		// comparators with tolerance for 3D Polygons
167*b1cdbd2cSJim Jagielski 		bool equal(const B3DPolygon& rCandidateA, const B3DPolygon& rCandidateB, const double& rfSmallValue);
168*b1cdbd2cSJim Jagielski 		bool equal(const B3DPolygon& rCandidateA, const B3DPolygon& rCandidateB);
169*b1cdbd2cSJim Jagielski 
170*b1cdbd2cSJim Jagielski 		/** snap some polygon coordinates to discrete coordinates
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski 			This method allows to snap some polygon points to discrete (integer) values
173*b1cdbd2cSJim Jagielski 			which equals e.g. a snap to discrete coordinates. It will snap points of
174*b1cdbd2cSJim Jagielski 			horizontal and vertical edges
175*b1cdbd2cSJim Jagielski 
176*b1cdbd2cSJim Jagielski 			@param rCandidate
177*b1cdbd2cSJim Jagielski 			The source polygon
178*b1cdbd2cSJim Jagielski 
179*b1cdbd2cSJim Jagielski 			@return
180*b1cdbd2cSJim Jagielski 			The modified version of the source polygon
181*b1cdbd2cSJim Jagielski 		*/
182*b1cdbd2cSJim Jagielski 		B3DPolygon snapPointsOfHorizontalOrVerticalEdges(const B3DPolygon& rCandidate);
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski 	} // end of namespace tools
185*b1cdbd2cSJim Jagielski } // end of namespace basegfx
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski #endif /* _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX */
188