Skip to content

Commit 5a8e351

Browse files
committed
Remove fragile and inefficient wkb re-parsing from TIN interpolator
1 parent e91ee5b commit 5a8e351

16 files changed

+509
-625
lines changed

src/analysis/interpolation/CloughTocherInterpolator.cpp

Lines changed: 59 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -151,81 +151,72 @@ bool CloughTocherInterpolator::calcNormVec( double x, double y, Vector3D *result
151151
}
152152
}
153153

154-
bool CloughTocherInterpolator::calcPoint( double x, double y, QgsPoint *result )
154+
bool CloughTocherInterpolator::calcPoint( double x, double y, QgsPoint &result )
155155
{
156-
if ( result )
156+
init( x, y );
157+
//find out, in which subtriangle the point (x,y) is
158+
QgsPoint barycoord( 0, 0, 0 );
159+
//is the point in the first subtriangle (point1,point2,cp10)?
160+
MathUtils::calcBarycentricCoordinates( x, y, &point1, &point2, &cp10, &barycoord );
161+
if ( barycoord.x() >= -mEdgeTolerance && barycoord.x() <= ( 1 + mEdgeTolerance ) && barycoord.y() >= -mEdgeTolerance && barycoord.y() <= ( 1 + mEdgeTolerance ) )
157162
{
158-
init( x, y );
159-
//find out, in which subtriangle the point (x,y) is
160-
QgsPoint barycoord( 0, 0, 0 );
161-
//is the point in the first subtriangle (point1,point2,cp10)?
162-
MathUtils::calcBarycentricCoordinates( x, y, &point1, &point2, &cp10, &barycoord );
163-
if ( barycoord.x() >= -mEdgeTolerance && barycoord.x() <= ( 1 + mEdgeTolerance ) && barycoord.y() >= -mEdgeTolerance && barycoord.y() <= ( 1 + mEdgeTolerance ) )
164-
{
165-
double z = point1.z() * calcBernsteinPoly( 3, 3, 0, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp1.z() * calcBernsteinPoly( 3, 2, 1, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp2.z() * calcBernsteinPoly( 3, 1, 2, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + point2.z() * calcBernsteinPoly( 3, 0, 3, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp3.z() * calcBernsteinPoly( 3, 2, 0, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp4.z() * calcBernsteinPoly( 3, 1, 1, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp5.z() * calcBernsteinPoly( 3, 0, 2, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp7.z() * calcBernsteinPoly( 3, 1, 0, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp8.z() * calcBernsteinPoly( 3, 0, 1, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp10.z() * calcBernsteinPoly( 3, 0, 0, 3, barycoord.x(), barycoord.y(), barycoord.z() );
166-
result->setX( x );
167-
result->setY( y );
168-
result->setZ( z );
169-
return true;
170-
}
171-
//is the point in the second subtriangle (point2,point3,cp10)?
172-
MathUtils::calcBarycentricCoordinates( x, y, &point2, &point3, &cp10, &barycoord );
173-
if ( barycoord.x() >= -mEdgeTolerance && barycoord.x() <= ( 1 + mEdgeTolerance ) && barycoord.y() >= -mEdgeTolerance && barycoord.y() <= ( 1 + mEdgeTolerance ) )
174-
{
175-
double z = cp10.z() * calcBernsteinPoly( 3, 0, 0, 3, barycoord.x(), barycoord.y(), barycoord.z() ) + cp8.z() * calcBernsteinPoly( 3, 1, 0, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp5.z() * calcBernsteinPoly( 3, 2, 0, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + point2.z() * calcBernsteinPoly( 3, 3, 0, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp12.z() * calcBernsteinPoly( 3, 0, 1, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp13.z() * calcBernsteinPoly( 3, 1, 1, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp9.z() * calcBernsteinPoly( 3, 2, 1, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp15.z() * calcBernsteinPoly( 3, 0, 2, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp16.z() * calcBernsteinPoly( 3, 1, 2, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + point3.z() * calcBernsteinPoly( 3, 0, 3, 0, barycoord.x(), barycoord.y(), barycoord.z() );
176-
result->setX( x );
177-
result->setY( y );
178-
result->setZ( z );
179-
return true;
180-
}
181-
//is the point in the third subtriangle (point3,point1,cp10)?
182-
MathUtils::calcBarycentricCoordinates( x, y, &point3, &point1, &cp10, &barycoord );
183-
if ( barycoord.x() >= -mEdgeTolerance && barycoord.x() <= ( 1 + mEdgeTolerance ) && barycoord.y() >= -mEdgeTolerance && barycoord.y() <= ( 1 + mEdgeTolerance ) )
184-
{
185-
double z = point1.z() * calcBernsteinPoly( 3, 0, 3, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp3.z() * calcBernsteinPoly( 3, 0, 2, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp7.z() * calcBernsteinPoly( 3, 0, 1, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp10.z() * calcBernsteinPoly( 3, 0, 0, 3, barycoord.x(), barycoord.y(), barycoord.z() ) + cp6.z() * calcBernsteinPoly( 3, 1, 2, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp11.z() * calcBernsteinPoly( 3, 1, 1, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp12.z() * calcBernsteinPoly( 3, 1, 0, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp14.z() * calcBernsteinPoly( 3, 2, 1, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp15.z() * calcBernsteinPoly( 3, 2, 0, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + point3.z() * calcBernsteinPoly( 3, 3, 0, 0, barycoord.x(), barycoord.y(), barycoord.z() );
186-
result->setX( x );
187-
result->setY( y );
188-
result->setZ( z );
189-
return true;
190-
}
191-
192-
//the point is in none of the subtriangles, test if point has the same position as one of the vertices
193-
if ( x == point1.x() && y == point1.y() )
194-
{
195-
result->setX( x );
196-
result->setY( y );
197-
result->setZ( point1.z() );
198-
return true;
199-
}
200-
else if ( x == point2.x() && y == point2.y() )
201-
{
202-
result->setX( x );
203-
result->setY( y );
204-
result->setZ( point2.z() );
205-
return true;
206-
}
207-
else if ( x == point3.x() && y == point3.y() )
208-
{
209-
result->setX( x );
210-
result->setY( y );
211-
result->setZ( point3.z() );
212-
return true;
213-
}
214-
else
215-
{
216-
result->setX( x );
217-
result->setY( y );
218-
result->setZ( 0 );
219-
}
220-
221-
return false;
163+
double z = point1.z() * calcBernsteinPoly( 3, 3, 0, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp1.z() * calcBernsteinPoly( 3, 2, 1, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp2.z() * calcBernsteinPoly( 3, 1, 2, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + point2.z() * calcBernsteinPoly( 3, 0, 3, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp3.z() * calcBernsteinPoly( 3, 2, 0, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp4.z() * calcBernsteinPoly( 3, 1, 1, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp5.z() * calcBernsteinPoly( 3, 0, 2, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp7.z() * calcBernsteinPoly( 3, 1, 0, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp8.z() * calcBernsteinPoly( 3, 0, 1, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp10.z() * calcBernsteinPoly( 3, 0, 0, 3, barycoord.x(), barycoord.y(), barycoord.z() );
164+
result.setX( x );
165+
result.setY( y );
166+
result.setZ( z );
167+
return true;
168+
}
169+
//is the point in the second subtriangle (point2,point3,cp10)?
170+
MathUtils::calcBarycentricCoordinates( x, y, &point2, &point3, &cp10, &barycoord );
171+
if ( barycoord.x() >= -mEdgeTolerance && barycoord.x() <= ( 1 + mEdgeTolerance ) && barycoord.y() >= -mEdgeTolerance && barycoord.y() <= ( 1 + mEdgeTolerance ) )
172+
{
173+
double z = cp10.z() * calcBernsteinPoly( 3, 0, 0, 3, barycoord.x(), barycoord.y(), barycoord.z() ) + cp8.z() * calcBernsteinPoly( 3, 1, 0, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp5.z() * calcBernsteinPoly( 3, 2, 0, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + point2.z() * calcBernsteinPoly( 3, 3, 0, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp12.z() * calcBernsteinPoly( 3, 0, 1, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp13.z() * calcBernsteinPoly( 3, 1, 1, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp9.z() * calcBernsteinPoly( 3, 2, 1, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp15.z() * calcBernsteinPoly( 3, 0, 2, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp16.z() * calcBernsteinPoly( 3, 1, 2, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + point3.z() * calcBernsteinPoly( 3, 0, 3, 0, barycoord.x(), barycoord.y(), barycoord.z() );
174+
result.setX( x );
175+
result.setY( y );
176+
result.setZ( z );
177+
return true;
178+
}
179+
//is the point in the third subtriangle (point3,point1,cp10)?
180+
MathUtils::calcBarycentricCoordinates( x, y, &point3, &point1, &cp10, &barycoord );
181+
if ( barycoord.x() >= -mEdgeTolerance && barycoord.x() <= ( 1 + mEdgeTolerance ) && barycoord.y() >= -mEdgeTolerance && barycoord.y() <= ( 1 + mEdgeTolerance ) )
182+
{
183+
double z = point1.z() * calcBernsteinPoly( 3, 0, 3, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp3.z() * calcBernsteinPoly( 3, 0, 2, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp7.z() * calcBernsteinPoly( 3, 0, 1, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp10.z() * calcBernsteinPoly( 3, 0, 0, 3, barycoord.x(), barycoord.y(), barycoord.z() ) + cp6.z() * calcBernsteinPoly( 3, 1, 2, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp11.z() * calcBernsteinPoly( 3, 1, 1, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + cp12.z() * calcBernsteinPoly( 3, 1, 0, 2, barycoord.x(), barycoord.y(), barycoord.z() ) + cp14.z() * calcBernsteinPoly( 3, 2, 1, 0, barycoord.x(), barycoord.y(), barycoord.z() ) + cp15.z() * calcBernsteinPoly( 3, 2, 0, 1, barycoord.x(), barycoord.y(), barycoord.z() ) + point3.z() * calcBernsteinPoly( 3, 3, 0, 0, barycoord.x(), barycoord.y(), barycoord.z() );
184+
result.setX( x );
185+
result.setY( y );
186+
result.setZ( z );
187+
return true;
188+
}
222189

190+
//the point is in none of the subtriangles, test if point has the same position as one of the vertices
191+
if ( x == point1.x() && y == point1.y() )
192+
{
193+
result.setX( x );
194+
result.setY( y );
195+
result.setZ( point1.z() );
196+
return true;
197+
}
198+
else if ( x == point2.x() && y == point2.y() )
199+
{
200+
result.setX( x );
201+
result.setY( y );
202+
result.setZ( point2.z() );
203+
return true;
204+
}
205+
else if ( x == point3.x() && y == point3.y() )
206+
{
207+
result.setX( x );
208+
result.setY( y );
209+
result.setZ( point3.z() );
210+
return true;
223211
}
224212
else
225213
{
226-
QgsDebugMsg( "warning, null pointer" );
227-
return false;
214+
result.setX( x );
215+
result.setY( y );
216+
result.setZ( 0 );
228217
}
218+
219+
return false;
229220
}
230221

231222
void CloughTocherInterpolator::init( double x, double y )//version, which has the unintended breaklines within the macrotriangles

src/analysis/interpolation/CloughTocherInterpolator.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ class ANALYSIS_EXPORT CloughTocherInterpolator : public TriangleInterpolator
107107

108108
//! Calculates the normal vector and assigns it to vec (not implemented at the moment)
109109
virtual bool calcNormVec( double x, double y, Vector3D *result SIP_OUT ) override;
110-
//! Performs a linear interpolation in a triangle and assigns the x-,y- and z-coordinates to point
111-
virtual bool calcPoint( double x, double y, QgsPoint *result SIP_OUT ) override;
110+
bool calcPoint( double x, double y, QgsPoint &result SIP_OUT ) override;
112111
virtual void setTriangulation( NormVecDecorator *tin );
113112
};
114113

0 commit comments

Comments
 (0)