32 const double t = ( ( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
48 const double dist = dx * dx + dy * dy;
63 const double f1 = x - x1;
64 const double f2 = y2 - y1;
65 const double f3 = y - y1;
66 const double f4 = x2 - x1;
67 const double test = ( f1 * f2 - f3 * f4 );
69 return qgsDoubleNear( test, 0.0 ) ? 0 : ( test < 0 ? -1 : 1 );
72void QgsGeometryUtilsBase::pointOnLineWithDistance(
double x1,
double y1,
double x2,
double y2,
double distance,
double &x,
double &y,
double *z1,
double *z2,
double *z,
double *m1,
double *m2,
double *m )
74 const double dx = x2 - x1;
75 const double dy = y2 - y1;
76 const double length = std::sqrt( dx * dx + dy * dy );
89 const double scaleFactor = distance / length;
90 x = x1 + dx * scaleFactor;
91 y = y1 + dy * scaleFactor;
93 *z = *z1 + ( *z2 - *z1 ) * scaleFactor;
95 *m = *m1 + ( *m2 - *m1 ) * scaleFactor;
102 const double mX = x1 + ( x2 - x1 ) * proportion;
103 const double mY = y1 + ( y2 - y1 ) * proportion;
104 const double pX = x1 - x2;
105 const double pY = y1 - y2;
106 double normalX = -pY;
108 const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) );
109 normalX /= normalLength;
110 normalY /= normalLength;
112 *x = mX + offset * normalX;
113 *y = mY + offset * normalY;
118 const double angle = std::atan2( dy, dx ) * 180 / M_PI;
123 else if ( angle > 360 )
132 if ( angle3 >= angle1 )
134 return !( angle2 > angle1 && angle2 < angle3 );
138 return !( angle2 > angle1 || angle2 < angle3 );
146 if ( angle2 < angle1 )
148 return ( angle <= angle1 && angle >= angle2 );
152 return ( angle <= angle1 || angle >= angle2 );
157 if ( angle2 > angle1 )
159 return ( angle >= angle1 && angle <= angle2 );
163 return ( angle >= angle1 || angle <= angle2 );
176 double dx21, dy21, dx31, dy31, h21, h31, d;
181 centerX = ( x1 + x2 ) / 2.0;
182 centerY = ( y1 + y2 ) / 2.0;
183 radius = std::sqrt( std::pow( centerX - x1, 2.0 ) + std::pow( centerY - y1, 2.0 ) );
193 h21 = std::pow( dx21, 2.0 ) + std::pow( dy21, 2.0 );
194 h31 = std::pow( dx31, 2.0 ) + std::pow( dy31, 2.0 );
197 d = 2 * ( dx21 * dy31 - dx31 * dy21 );
207 centerX = x1 + ( h21 * dy31 - h31 * dy21 ) / d;
208 centerY = y1 - ( h21 * dx31 - h31 * dx21 ) / d;
209 radius = std::sqrt( std::pow( centerX - x1, 2.0 ) + std::pow( centerY - y1, 2.0 ) );
214 double centerX { 0.0 };
215 double centerY { 0.0 };
216 double radius { 0.0 };
218 double length = M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
226double QgsGeometryUtilsBase::calculateArcLength(
double centerX,
double centerY,
double radius,
double x1,
double y1,
double x2,
double y2,
double x3,
double y3,
int fromVertex,
int toVertex )
228 if ( fromVertex == toVertex )
231 if ( fromVertex < 0 || fromVertex > 2 || toVertex < 0 || toVertex > 2 )
241 bool clockwise = totalSweepAngle < 0;
244 double fromAngle, toAngle;
245 if ( fromVertex == 0 )
247 else if ( fromVertex == 1 )
254 else if ( toVertex == 1 )
260 double arcAngleDegrees;
263 arcAngleDegrees = fromAngle - toAngle;
264 if ( arcAngleDegrees <= 0 )
266 arcAngleDegrees += 360.0;
271 arcAngleDegrees = toAngle - fromAngle;
272 if ( arcAngleDegrees <= 0 )
274 arcAngleDegrees += 360.0;
280 double totalArcAngleDegrees = std::abs( totalSweepAngle );
281 if ( arcAngleDegrees > totalArcAngleDegrees && ( fromVertex == 0 && toVertex == 2 ) ==
false )
284 arcAngleDegrees = 360.0 - arcAngleDegrees;
288 const double arcAngleRadians = arcAngleDegrees * M_PI / 180.0;
289 return radius * arcAngleRadians;
298 if ( p3Angle >= p1Angle )
300 if ( p2Angle > p1Angle && p2Angle < p3Angle )
302 return ( p3Angle - p1Angle );
306 return ( -( p1Angle + ( 360 - p3Angle ) ) );
311 if ( p2Angle < p1Angle && p2Angle > p3Angle )
313 return ( -( p1Angle - p3Angle ) );
317 return ( p3Angle + ( 360 - p1Angle ) );
328 return zm1 + ( zm2 - zm1 ) * ( angle - a1 ) / ( a2 - a1 );
330 return zm2 + ( zm3 - zm2 ) * ( angle - a2 ) / ( a3 - a2 );
336 return zm1 + ( zm2 - zm1 ) * ( a1 - angle ) / ( a1 - a2 );
338 return zm2 + ( zm3 - zm2 ) * ( a2 - angle ) / ( a2 - a3 );
343 double clippedAngle = angle;
344 if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
346 clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
348 if ( clippedAngle < 0.0 )
350 clippedAngle += 2 * M_PI;
359 if ( x <= left && y <= bottom )
361 const double dx = left - x;
362 const double dy = bottom - y;
370 else if ( x >= right && y >= top )
372 const double dx = x - right;
373 const double dy = y - top;
381 else if ( x >= right && y <= bottom )
383 const double dx = x - right;
384 const double dy = bottom - y;
392 else if ( x <= left && y >= top )
394 const double dx = left - x;
395 const double dy = y - top;
403 else if ( x <= left )
405 else if ( x >= right )
407 else if ( y <= bottom )
413 const double smallestX = std::min( right - x, x - left );
414 const double smallestY = std::min( top - y, y - bottom );
415 if ( smallestX < smallestY )
418 if ( right - x < x - left )
426 if ( top - y < y - bottom )
436 double segmentPoint1x,
437 double segmentPoint1y,
438 double segmentPoint2x,
439 double segmentPoint2y,
440 double &perpendicularSegmentPoint1x,
441 double &perpendicularSegmentPoint1y,
442 double &perpendicularSegmentPoint2x,
443 double &perpendicularSegmentPoint2y,
444 double desiredSegmentLength
447 QgsVector segmentVector =
QgsVector( segmentPoint2x - segmentPoint1x, segmentPoint2y - segmentPoint1y );
449 if ( desiredSegmentLength != 0 )
451 perpendicularVector = perpendicularVector.
normalized() * ( desiredSegmentLength ) / 2;
454 perpendicularSegmentPoint1x = pointx - perpendicularVector.
x();
455 perpendicularSegmentPoint1y = pointy - perpendicularVector.
y();
456 perpendicularSegmentPoint2x = pointx + perpendicularVector.
x();
457 perpendicularSegmentPoint2y = pointy + perpendicularVector.
y();
462 const double at = std::atan2( y2 - y1, x2 - x1 );
463 const double a = -at + M_PI_2;
469 const double angle1 = std::atan2( y1 - y2, x1 - x2 );
470 const double angle2 = std::atan2( y3 - y2, x3 - x2 );
484 const double a1 =
lineAngle( x1, y1, x2, y2 );
485 const double a2 =
lineAngle( x2, y2, x3, y3 );
493 double clockwiseDiff = 0.0;
496 clockwiseDiff = a2 - a1;
500 clockwiseDiff = a2 + ( 2 * M_PI - a1 );
502 const double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
504 double resultAngle = 0;
505 if ( clockwiseDiff <= counterClockwiseDiff )
507 resultAngle = a1 + clockwiseDiff / 2.0;
511 resultAngle = a1 - counterClockwiseDiff / 2.0;
537 if ( std::fabs( u3.
x() ) <= epsilon && std::fabs( u3.
y() ) <= epsilon && std::fabs( u3.
z() ) <= epsilon )
549 if ( !( std::fabs( b1 ) > epsilon ) )
554 if ( !( a2 != -1 && a2 != 1 ) )
560 const double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
568 const double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
573 const double dx = p2x - p1x;
574 const double dy = p2y - p1y;
575 const double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
577 intersectionX = p1x + v1.
x() * k;
578 intersectionY = p1y + v1.
y() * k;
587 const QgsVector v1( std::sin( bearing1 ), std::cos( bearing1 ) );
588 const QgsVector v2( std::sin( bearing2 ), std::cos( bearing2 ) );
590 return lineIntersection( x1, y1, v1, x2, y2, v2, intersectionX, intersectionY );
593static bool equals(
double p1x,
double p1y,
double p2x,
double p2y,
double epsilon = 1e-8 )
599 double p1x,
double p1y,
double p2x,
double p2y,
double q1x,
double q1y,
double q2x,
double q2y,
double &intersectionPointX,
double &intersectionPointY,
bool &isIntersection,
double tolerance,
bool acceptImproperIntersection
602 isIntersection =
false;
603 intersectionPointX = intersectionPointY = std::numeric_limits<double>::quiet_NaN();
607 const double vl = v.
length();
608 const double wl = w.
length();
617 if ( !
lineIntersection( p1x, p1y, v, q1x, q1y, w, intersectionPointX, intersectionPointY ) )
622 isIntersection =
true;
623 if ( acceptImproperIntersection )
625 if ( ( equals( p1x, p1y, q1x, q1y ) ) || ( equals( p1x, p1y, q2x, q2y ) ) )
627 intersectionPointX = p1x;
628 intersectionPointY = p1y;
631 else if ( ( equals( p1x, p1y, q2x, q2y ) ) || ( equals( p2x, p2y, q2x, q2y ) ) )
633 intersectionPointX = p2x;
634 intersectionPointY = p2y;
641 qgsDoubleNear(
sqrDistToLine( p1x, p1y, q1x, q1y, q2x, q2y, x, y, tolerance ), 0.0, tolerance ) ||
643 qgsDoubleNear(
sqrDistToLine( p2x, p2y, q1x, q1y, q2x, q2y, x, y, tolerance ), 0.0, tolerance ) ||
645 qgsDoubleNear(
sqrDistToLine( q1x, q1y, p1x, p1y, p2x, p2y, x, y, tolerance ), 0.0, tolerance ) ||
647 qgsDoubleNear(
sqrDistToLine( q2x, q2y, p1x, p1y, p2x, p2y, x, y, tolerance ), 0.0, tolerance )
654 const double lambdav =
QgsVector( intersectionPointX - p1x, intersectionPointY - p1y ) * v;
655 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
658 const double lambdaw =
QgsVector( intersectionPointX - q1x, intersectionPointY - q1y ) * w;
659 return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
669 double ptInterX = 0.0, ptInterY = 0.0;
670 bool isIntersection =
false;
671 segmentIntersection( La1.
x(), La1.
y(), La2.
x(), La2.
y(), Lb1.
x(), Lb1.
y(), Lb2.
x(), Lb2.
y(), ptInterX, ptInterY, isIntersection, 1e-8,
true );
672 intersection.
set( ptInterX, ptInterY, La1.
z() );
712 if ( !firstIsDone || !secondIsDone )
718 intersection = ( X1 + X2 ) / 2.0;
724 return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
729 const double dxp = px - x1;
730 const double dyp = py - y1;
732 const double dxl = x2 - x1;
733 const double dyl = y2 - y1;
735 return std::sqrt( ( dxp * dxp ) + ( dyp * dyp ) ) / std::sqrt( ( dxl * dxl ) + ( dyl * dyl ) );
739 const double aX,
const double aY,
const double bX,
const double bY,
const double cX,
const double cY,
double weightB,
double weightC,
double &pointX,
double &pointY
743 if ( weightB + weightC > 1 )
745 weightB = 1 - weightB;
746 weightC = 1 - weightC;
749 const double rBx = weightB * ( bX - aX );
750 const double rBy = weightB * ( bY - aY );
751 const double rCx = weightC * ( cX - aX );
752 const double rCy = weightC * ( cY - aY );
754 pointX = rBx + rCx + aX;
755 pointY = rBy + rCy + aY;
760 return qgsDoubleNear( x1 * ( y2 - y3 ) + x2 * ( y3 - y1 ) + x3 * ( y1 - y2 ), 0, epsilon );
766 const double cx = ( y2 - y1 ) * ( z3 - z1 ) - ( z2 - z1 ) * ( y3 - y1 );
767 const double cy = ( z2 - z1 ) * ( x3 - x1 ) - ( x2 - x1 ) * ( z3 - z1 );
768 const double cz = ( x2 - x1 ) * ( y3 - y1 ) - ( y2 - y1 ) * ( x3 - x1 );
771 return qgsDoubleNear( cx * cx + cy * cy + cz * cz, 0.0, epsilon * epsilon );
776 const double dx = x2 - x1;
777 const double dy = y2 - y1;
778 return ( std::atan2( dx, dy ) * 180.0 / M_PI );
781bool QgsGeometryUtilsBase::angleBisector(
double aX,
double aY,
double bX,
double bY,
double cX,
double cY,
double dX,
double dY,
double &pointX,
double &pointY,
double &angle )
783 angle = (
azimuth( aX, aY, bX, bY ) +
azimuth( cX, cY, dX, dY ) ) / 2.0;
785 bool intersection =
false;
786 QgsGeometryUtilsBase::segmentIntersection( aX, aY, bX, bY, cX, cY, dX, dY, pointX, pointY, intersection );
793 const double radsXy =
azimuth * M_PI / 180.0;
794 double dx = 0.0, dy = 0.0, dz = 0.0;
796 inclination = std::fmod( inclination, 360.0 );
798 if ( std::isnan( aZ ) &&
qgsDoubleNear( inclination, 90.0 ) )
800 dx = distance * std::sin( radsXy );
801 dy = distance * std::cos( radsXy );
805 const double radsZ = inclination * M_PI / 180.0;
806 dx = distance * std::sin( radsZ ) * std::sin( radsXy );
807 dy = distance * std::sin( radsZ ) * std::cos( radsXy );
808 dz = distance * std::cos( radsZ );
818 const double angle = (
azimuth( aX, aY, bX, bY ) +
azimuth( aX, aY, cX, cY ) ) / 2.0;
820 bool intersection =
false;
821 double dX = 0.0, dY = 0.0, dZ = 0.0;
822 project( aX, aY, std::numeric_limits<double>::quiet_NaN(), 1.0, angle, 90.0, dX, dY, dZ );
823 segmentIntersection( bX, bY, cX, cY, aX, aY, dX, dY, pointX, pointY, intersection );
830 const double segment1StartX,
831 const double segment1StartY,
832 const double segment1EndX,
833 const double segment1EndY,
834 const double segment2StartX,
835 const double segment2StartY,
836 const double segment2EndX,
837 const double segment2EndY,
841 double intersectionX, intersectionY;
844 segmentIntersection( segment1StartX, segment1StartY, segment1EndX, segment1EndY, segment2StartX, segment2StartY, segment2EndX, segment2EndY, intersectionX, intersectionY, isIntersection, epsilon,
true );
846 if ( !isIntersection )
856 const double dir1X = dist1ToStart > epsilon ? segment1StartX : segment1EndX;
857 const double dir1Y = dist1ToStart > epsilon ? segment1StartY : segment1EndY;
858 const double dir2X = dist2ToStart > epsilon ? segment2StartX : segment2EndX;
859 const double dir2Y = dist2ToStart > epsilon ? segment2StartY : segment2EndY;
863 if ( std::abs( angle ) < epsilon || std::abs( angle - M_PI ) < epsilon )
868 double workingAngle = angle;
869 if ( workingAngle > M_PI )
871 workingAngle = 2 * M_PI - workingAngle;
874 const double halfAngle = workingAngle / 2.0;
875 if ( std::abs( std::sin( halfAngle ) ) < epsilon )
880 const double maxDist1 = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
881 const double maxDist2 = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
886 const bool intersectionOnSeg1 = std::abs( ( dist1ToStart + dist1ToEnd ) - seg1Length ) < epsilon;
887 const bool intersectionOnSeg2 = std::abs( ( dist2ToStart + dist2ToEnd ) - seg2Length ) < epsilon;
889 double maxDistanceToTangent = std::numeric_limits<double>::max();
891 if ( intersectionOnSeg1 )
893 maxDistanceToTangent = std::min( maxDistanceToTangent, maxDist1 - epsilon );
896 if ( intersectionOnSeg2 )
898 maxDistanceToTangent = std::min( maxDistanceToTangent, maxDist2 - epsilon );
901 if ( maxDistanceToTangent == std::numeric_limits<double>::max() )
903 maxDistanceToTangent = std::min( maxDist1, maxDist2 ) - epsilon;
906 if ( maxDistanceToTangent <= 0 )
911 return maxDistanceToTangent * std::tan( halfAngle );
915 const double segment1StartX,
916 const double segment1StartY,
917 const double segment1EndX,
918 const double segment1EndY,
919 const double segment2StartX,
920 const double segment2StartY,
921 const double segment2EndX,
922 const double segment2EndY,
924 double *filletPointsX,
925 double *filletPointsY,
941 double intersectionX, intersectionY;
944 segmentIntersection( segment1StartX, segment1StartY, segment1EndX, segment1EndY, segment2StartX, segment2StartY, segment2EndX, segment2EndY, intersectionX, intersectionY, isIntersection, epsilon,
true );
946 if ( !isIntersection )
959 const double dir1X = dist1ToStart > epsilon ? segment1StartX : segment1EndX;
960 const double dir1Y = dist1ToStart > epsilon ? segment1StartY : segment1EndY;
961 const double dir2X = dist2ToStart > epsilon ? segment2StartX : segment2EndX;
962 const double dir2Y = dist2ToStart > epsilon ? segment2StartY : segment2EndY;
968 if ( std::abs( angle ) < epsilon || std::abs( angle - M_PI ) < epsilon )
974 double workingAngle = angle;
975 if ( workingAngle > M_PI )
977 workingAngle = 2 * M_PI - workingAngle;
980 const double halfAngle = workingAngle / 2.0;
981 if ( std::abs( std::sin( halfAngle ) ) < epsilon )
988 const double distanceToTangent = radius / std::tan( halfAngle );
990 const double maxDist1 = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
991 const double maxDist2 = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
997 const bool intersectionOnSeg1 = std::abs( ( dist1ToStart + dist1ToEnd ) - seg1Length ) < epsilon;
998 const bool intersectionOnSeg2 = std::abs( ( dist2ToStart + dist2ToEnd ) - seg2Length ) < epsilon;
1002 if ( intersectionOnSeg1 && distanceToTangent > maxDist1 - epsilon )
1007 if ( intersectionOnSeg2 && distanceToTangent > maxDist2 - epsilon )
1013 double T1x, T1y, T2x, T2y;
1018 const QgsVector v1( dir1X - intersectionX, dir1Y - intersectionY );
1019 const QgsVector v2( dir2X - intersectionX, dir2Y - intersectionY );
1025 const double centerDistance = radius / std::sin( halfAngle );
1026 const double centerX = intersectionX + bisectorDirection.
x() * centerDistance;
1027 const double centerY = intersectionY + bisectorDirection.
y() * centerDistance;
1032 const QgsVector midDirection = ( centerToT1 + centerToT2 ).normalized();
1034 const double midX = centerX + midDirection.
x() * radius;
1035 const double midY = centerY + midDirection.
y() * radius;
1038 filletPointsX[0] = T1x;
1039 filletPointsY[0] = T1y;
1040 filletPointsX[1] = midX;
1041 filletPointsY[1] = midY;
1042 filletPointsX[2] = T2x;
1043 filletPointsY[2] = T2y;
1048 if ( dist1ToStart > epsilon )
1050 *trim1StartX = segment1StartX;
1051 *trim1StartY = segment1StartY;
1055 *trim1StartX = segment1EndX;
1056 *trim1StartY = segment1EndY;
1063 if ( dist2ToStart > epsilon )
1065 *trim2StartX = segment2StartX;
1066 *trim2StartY = segment2StartY;
1070 *trim2StartX = segment2EndX;
1071 *trim2StartY = segment2EndY;
1081 const double segment1StartX,
1082 const double segment1StartY,
1083 const double segment1EndX,
1084 const double segment1EndY,
1085 const double segment2StartX,
1086 const double segment2StartY,
1087 const double segment2EndX,
1088 const double segment2EndY,
1091 double &chamferStartX,
1092 double &chamferStartY,
1093 double &chamferEndX,
1094 double &chamferEndY,
1095 double *trim1StartX,
1096 double *trim1StartY,
1099 double *trim2StartX,
1100 double *trim2StartY,
1103 const double epsilon
1107 if ( distance2 <= 0 )
1108 distance2 = distance1;
1111 if ( distance1 <= 0 || distance2 <= 0 )
1115 double intersectionX, intersectionY;
1116 bool isIntersection;
1118 segmentIntersection( segment1StartX, segment1StartY, segment1EndX, segment1EndY, segment2StartX, segment2StartY, segment2EndX, segment2EndY, intersectionX, intersectionY, isIntersection, epsilon,
true );
1120 if ( !isIntersection )
1126 if ( distance2 < 0 )
1127 distance2 = distance1;
1138 if ( dist1ToStart > epsilon )
1148 if ( dist2ToStart > epsilon )
1158 const double distToSeg1Target = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
1159 const double distToSeg2Target = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
1161 if ( distance1 > distToSeg1Target - epsilon )
1163 if ( dist1ToStart > epsilon )
1173 if ( distance2 > distToSeg2Target - epsilon )
1175 if ( dist2ToStart > epsilon )
1185 chamferStartX = T1x;
1186 chamferStartY = T1y;
1193 if ( dist1ToStart > epsilon )
1195 *trim1StartX = segment1StartX;
1196 *trim1StartY = segment1StartY;
1202 *trim1StartX = segment1EndX;
1203 *trim1StartY = segment1EndY;
1210 if ( dist2ToStart > epsilon )
1212 *trim2StartX = segment2StartX;
1213 *trim2StartY = segment2StartY;
1219 *trim2StartX = segment2EndX;
1220 *trim2StartY = segment2EndY;
static double circleLength(double x1, double y1, double x2, double y2, double x3, double y3)
Length of a circular string segment defined by pt1, pt2, pt3.
static double calculateArcLength(double centerX, double centerY, double radius, double x1, double y1, double x2, double y2, double x3, double y3, int fromVertex, int toVertex)
Calculates the precise arc length between two vertices on a circular arc.
static void pointOnLineWithDistance(double x1, double y1, double x2, double y2, double distance, double &x, double &y, double *z1=nullptr, double *z2=nullptr, double *z=nullptr, double *m1=nullptr, double *m2=nullptr, double *m=nullptr)
Calculates the point a specified distance from (x1, y1) toward a second point (x2,...
static double angleBetweenThreePoints(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the angle between the lines AB and BC, where AB and BC described by points a,...
static double maximumFilletRadius(const double segment1StartX, const double segment1StartY, const double segment1EndX, const double segment1EndY, const double segment2StartX, const double segment2StartY, const double segment2EndX, const double segment2EndY, double epsilon=1e-8)
Calculates the maximum allowed fillet radius for the given segment configuration.
static double ccwAngle(double dy, double dx)
Returns the counter clockwise angle between a line with components dx, dy and the line with dx > 0 an...
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if the circle defined by three angles is ordered clockwise.
static double distance2D(double x1, double y1, double x2, double y2)
Returns the 2D distance between (x1, y1) and (x2, y2).
static double sweepAngle(double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3)
Calculates angle of a circular string part defined by pt1, pt2, pt3.
static bool createChamfer(const double segment1StartX, const double segment1StartY, const double segment1EndX, const double segment1EndY, const double segment2StartX, const double segment2StartY, const double segment2EndX, const double segment2EndY, const double distance1, const double distance2, double &chamferStartX, double &chamferStartY, double &chamferEndX, double &chamferEndY, double *trim1StartX=nullptr, double *trim1StartY=nullptr, double *trim1EndX=nullptr, double *trim1EndY=nullptr, double *trim2StartX=nullptr, double *trim2StartY=nullptr, double *trim2EndX=nullptr, double *trim2EndY=nullptr, const double epsilon=1e-8)
Creates a chamfer (angled corner) between two line segments.
static double linePerpendicularAngle(double x1, double y1, double x2, double y2)
Calculates the perpendicular angle to a line joining two points.
static bool bisector(double aX, double aY, double bX, double bY, double cX, double cY, double &pointX, double &pointY)
Returns the point (pointX, pointY) forming the bisector from point (aX, aY) to the segment (bX,...
static double lineAngle(double x1, double y1, double x2, double y2)
Calculates the direction of line joining two points in radians, clockwise from the north direction.
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the average angle (in radians) between the two linear segments from (x1,...
static bool skewLinesProjection(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22, QgsVector3D &X1, double epsilon=0.0001)
A method to project one skew line onto another.
static bool points3DAreCollinear(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double epsilon)
Given the points (x1, y1, z1), (x2, y2, z2) and (x3, y3, z3) returns true if these points can be cons...
static int closestSideOfRectangle(double right, double bottom, double left, double top, double x, double y)
Returns a number representing the closest side of a rectangle defined by /a right,...
static void project(double aX, double aY, double aZ, double distance, double azimuth, double inclination, double &resultX, double &resultY, double &resultZ)
Returns coordinates of a point which corresponds to this point projected by a specified distance with...
static double interpolateArcValue(double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3)
Interpolate a value at given angle on circular arc given values (zm1, zm2, zm3) at three different an...
static void perpendicularOffsetPointAlongSegment(double x1, double y1, double x2, double y2, double proportion, double offset, double *x, double *y)
Calculates a point a certain proportion of the way along the segment from (x1, y1) to (x2,...
static double skewLinesDistance(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22)
An algorithm to calculate the shortest distance between two skew lines.
static double pointFractionAlongLine(double x1, double y1, double x2, double y2, double px, double py)
Given the line (x1, y1) to (x2, y2) and a point (px, py) returns the fraction of the line length at w...
static double normalizedAngle(double angle)
Ensures that an angle is in the range 0 <= angle < 2 pi.
static void weightedPointInTriangle(double aX, double aY, double bX, double bY, double cX, double cY, double weightB, double weightC, double &pointX, double &pointY)
Returns a weighted point inside the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
static void perpendicularCenterSegment(double centerPointX, double centerPointY, double segmentPoint1x, double segmentPoint1y, double segmentPoint2x, double segmentPoint2y, double &perpendicularSegmentPoint1x, double &perpendicularSegmentPoint1y, double &perpendicularSegmentPoint2x, double &perpendicularSegmentPoint2y, double segmentLength=0)
Create a perpendicular line segment to a given segment [segmentPoint1,segmentPoint2] with its center ...
static bool circleAngleBetween(double angle, double angle1, double angle2, bool clockwise)
Returns true if, in a circle, angle is between angle1 and angle2.
static double triangleArea(double aX, double aY, double bX, double bY, double cX, double cY)
Returns the area of the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
static bool angleBisector(double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY, double &pointX, double &pointY, double &angle)
Returns the point (pointX, pointY) forming the bisector from segment (aX aY) (bX bY) and segment (bX,...
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon)
Returns the squared distance between a point and a line.
static bool intersectionPointOfLinesByBearing(double x1, double y1, double bearing1, double x2, double y2, double bearing2, double &intersectionX, double &intersectionY)
Calculates the intersection point of two lines defined by point and bearing.
static bool angleOnCircle(double angle, double angle1, double angle2, double angle3)
Returns true if an angle is between angle1 and angle3 on a circle described by angle1,...
static bool segmentIntersection(double p1x, double p1y, double p2x, double p2y, double q1x, double q1y, double q2x, double q2y, double &intersectionPointX, double &intersectionPointY, bool &isIntersection, double tolerance=1e-8, bool acceptImproperIntersection=false)
Compute the intersection between two segments.
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2)
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
static bool linesIntersection3D(const QgsVector3D &La1, const QgsVector3D &La2, const QgsVector3D &Lb1, const QgsVector3D &Lb2, QgsVector3D &intersection)
An algorithm to calculate an (approximate) intersection of two lines in 3D.
static bool pointsAreCollinear(double x1, double y1, double x2, double y2, double x3, double y3, double epsilon)
Given the points (x1, y1), (x2, y2) and (x3, y3) returns true if these points can be considered colli...
static void circleCenterRadius(double x1, double y1, double x2, double y2, double x3, double y3, double &radius, double ¢erX, double ¢erY)
Returns radius and center of the circle through (x1 y1), (x2 y2), (x3 y3).
static bool createFillet(const double segment1StartX, const double segment1StartY, const double segment1EndX, const double segment1EndY, const double segment2StartX, const double segment2StartY, const double segment2EndX, const double segment2EndY, const double radius, double *filletPointsX, double *filletPointsY, double *trim1StartX=nullptr, double *trim1StartY=nullptr, double *trim1EndX=nullptr, double *trim1EndY=nullptr, double *trim2StartX=nullptr, double *trim2StartY=nullptr, double *trim2EndX=nullptr, double *trim2EndY=nullptr, const double epsilon=1e-8)
Creates a fillet (rounded corner) between two line segments.
static bool lineIntersection(double p1x, double p1y, QgsVector v1, double p2x, double p2y, QgsVector v2, double &intersectionX, double &intersectionY)
Computes the intersection between two lines.
static double azimuth(double x1, double y1, double x2, double y2)
Calculates Cartesian azimuth between points (x1, y1) and (x2, y2) (clockwise in degree,...
Custom exception class when argument are invalid.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
static double dotProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the dot product of two vectors.
double x() const
Returns X coordinate.
void normalize()
Normalizes the current vector in place.
static QgsVector3D crossProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the cross product of two vectors.
void set(double x, double y, double z)
Sets vector coordinates.
double length() const
Returns the length of the vector.
Represent a 2-dimensional vector.
double y() const
Returns the vector's y-component.
QgsVector normalized() const
Returns the vector's normalized (or "unit") vector (ie same angle but length of 1....
QgsVector perpVector() const
Returns the perpendicular vector to this vector (rotated 90 degrees counter-clockwise).
double x() const
Returns the vector's x-component.
double length() const
Returns the length of the vector.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).