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 ) );
218 double length = M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
227 double x1,
double y1,
double x2,
double y2,
228 double x3,
double y3,
int fromVertex,
int toVertex )
230 if ( fromVertex == toVertex )
233 if ( fromVertex < 0 || fromVertex > 2 || toVertex < 0 || toVertex > 2 )
243 bool clockwise = totalSweepAngle < 0;
246 double fromAngle, toAngle;
247 if ( fromVertex == 0 )
249 else if ( fromVertex == 1 )
256 else if ( toVertex == 1 )
262 double arcAngleDegrees;
265 arcAngleDegrees = fromAngle - toAngle;
266 if ( arcAngleDegrees <= 0 )
268 arcAngleDegrees += 360.0;
273 arcAngleDegrees = toAngle - fromAngle;
274 if ( arcAngleDegrees <= 0 )
276 arcAngleDegrees += 360.0;
282 double totalArcAngleDegrees = std::abs( totalSweepAngle );
283 if ( arcAngleDegrees > totalArcAngleDegrees && ( fromVertex == 0 && toVertex == 2 ) ==
false )
286 arcAngleDegrees = 360.0 - arcAngleDegrees;
290 const double arcAngleRadians = arcAngleDegrees * M_PI / 180.0;
291 return radius * arcAngleRadians;
300 if ( p3Angle >= p1Angle )
302 if ( p2Angle > p1Angle && p2Angle < p3Angle )
304 return ( p3Angle - p1Angle );
308 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
313 if ( p2Angle < p1Angle && p2Angle > p3Angle )
315 return ( -( p1Angle - p3Angle ) );
319 return ( p3Angle + ( 360 - p1Angle ) );
330 return zm1 + ( zm2 - zm1 ) * ( angle - a1 ) / ( a2 - a1 );
332 return zm2 + ( zm3 - zm2 ) * ( angle - a2 ) / ( a3 - a2 );
338 return zm1 + ( zm2 - zm1 ) * ( a1 - angle ) / ( a1 - a2 );
340 return zm2 + ( zm3 - zm2 ) * ( a2 - angle ) / ( a2 - a3 );
345 double clippedAngle = angle;
346 if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
348 clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
350 if ( clippedAngle < 0.0 )
352 clippedAngle += 2 * M_PI;
361 if ( x <= left && y <= bottom )
363 const double dx = left - x;
364 const double dy = bottom - y;
372 else if ( x >= right && y >= top )
374 const double dx = x - right;
375 const double dy = y - top;
383 else if ( x >= right && y <= bottom )
385 const double dx = x - right;
386 const double dy = bottom - y;
394 else if ( x <= left && y >= top )
396 const double dx = left - x;
397 const double dy = y - top;
405 else if ( x <= left )
407 else if ( x >= right )
409 else if ( y <= bottom )
415 const double smallestX = std::min( right - x, x - left );
416 const double smallestY = std::min( top - y, y - bottom );
417 if ( smallestX < smallestY )
420 if ( right - x < x - left )
428 if ( top - y < y - bottom )
435void QgsGeometryUtilsBase::perpendicularCenterSegment(
double pointx,
double pointy,
double segmentPoint1x,
double segmentPoint1y,
double segmentPoint2x,
double segmentPoint2y,
double &perpendicularSegmentPoint1x,
double &perpendicularSegmentPoint1y,
double &perpendicularSegmentPoint2x,
double &perpendicularSegmentPoint2y,
double desiredSegmentLength )
437 QgsVector segmentVector =
QgsVector( segmentPoint2x - segmentPoint1x, segmentPoint2y - segmentPoint1y );
439 if ( desiredSegmentLength != 0 )
441 perpendicularVector = perpendicularVector.
normalized() * ( desiredSegmentLength ) / 2;
444 perpendicularSegmentPoint1x = pointx - perpendicularVector.
x();
445 perpendicularSegmentPoint1y = pointy - perpendicularVector.
y();
446 perpendicularSegmentPoint2x = pointx + perpendicularVector.
x();
447 perpendicularSegmentPoint2y = pointy + perpendicularVector.
y();
452 const double at = std::atan2( y2 - y1, x2 - x1 );
453 const double a = -at + M_PI_2;
459 const double angle1 = std::atan2( y1 - y2, x1 - x2 );
460 const double angle2 = std::atan2( y3 - y2, x3 - x2 );
474 const double a1 =
lineAngle( x1, y1, x2, y2 );
475 const double a2 =
lineAngle( x2, y2, x3, y3 );
483 double clockwiseDiff = 0.0;
486 clockwiseDiff = a2 - a1;
490 clockwiseDiff = a2 + ( 2 * M_PI - a1 );
492 const double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
494 double resultAngle = 0;
495 if ( clockwiseDiff <= counterClockwiseDiff )
497 resultAngle = a1 + clockwiseDiff / 2.0;
501 resultAngle = a1 - counterClockwiseDiff / 2.0;
512 if ( u3.
length() == 0 )
return 1;
529 if ( std::fabs( u3.
x() ) <= epsilon &&
530 std::fabs( u3.
y() ) <= epsilon &&
531 std::fabs( u3.
z() ) <= epsilon )
543 if ( !( std::fabs( b1 ) > epsilon ) )
548 if ( !( a2 != -1 && a2 != 1 ) )
554 const double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
562 const double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
567 const double dx = p2x - p1x;
568 const double dy = p2y - p1y;
569 const double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
571 intersectionX = p1x + v1.
x() * k;
572 intersectionY = p1y + v1.
y() * k;
581 const QgsVector v1( std::sin( bearing1 ), std::cos( bearing1 ) );
582 const QgsVector v2( std::sin( bearing2 ), std::cos( bearing2 ) );
584 return lineIntersection( x1, y1, v1, x2, y2, v2, intersectionX, intersectionY );
587static bool equals(
double p1x,
double p1y,
double p2x,
double p2y,
double epsilon = 1e-8 )
592bool QgsGeometryUtilsBase::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,
bool acceptImproperIntersection )
594 isIntersection =
false;
595 intersectionPointX = intersectionPointY = std::numeric_limits<double>::quiet_NaN();
599 const double vl = v.
length();
600 const double wl = w.
length();
609 if ( !
lineIntersection( p1x, p1y, v, q1x, q1y, w, intersectionPointX, intersectionPointY ) )
614 isIntersection =
true;
615 if ( acceptImproperIntersection )
617 if ( ( equals( p1x, p1y, q1x, q1y ) ) || ( equals( p1x, p1y, q2x, q2y ) ) )
619 intersectionPointX = p1x;
620 intersectionPointY = p1y;
623 else if ( ( equals( p1x, p1y, q2x, q2y ) ) || ( equals( p2x, p2y, q2x, q2y ) ) )
625 intersectionPointX = p2x;
626 intersectionPointY = p2y;
633 qgsDoubleNear(
sqrDistToLine( p1x, p1y, q1x, q1y, q2x, q2y, x, y, tolerance ), 0.0, tolerance ) ||
635 qgsDoubleNear(
sqrDistToLine( p2x, p2y, q1x, q1y, q2x, q2y, x, y, tolerance ), 0.0, tolerance ) ||
637 qgsDoubleNear(
sqrDistToLine( q1x, q1y, p1x, p1y, p2x, p2y, x, y, tolerance ), 0.0, tolerance ) ||
639 qgsDoubleNear(
sqrDistToLine( q2x, q2y, p1x, p1y, p2x, p2y, x, y, tolerance ), 0.0, tolerance )
646 const double lambdav =
QgsVector( intersectionPointX - p1x, intersectionPointY - p1y ) * v;
647 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
650 const double lambdaw =
QgsVector( intersectionPointX - q1x, intersectionPointY - q1y ) * w;
651 return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
665 double ptInterX = 0.0, ptInterY = 0.0;
666 bool isIntersection =
false;
675 intersection.
set( ptInterX, ptInterY, La1.
z() );
715 if ( !firstIsDone || !secondIsDone )
721 intersection = ( X1 + X2 ) / 2.0;
727 return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
732 const double dxp = px - x1;
733 const double dyp = py - y1;
735 const double dxl = x2 - x1;
736 const double dyl = y2 - y1;
738 return std::sqrt( ( dxp * dxp ) + ( dyp * dyp ) ) / std::sqrt( ( dxl * dxl ) + ( dyl * dyl ) );
742 double weightB,
double weightC,
double &pointX,
double &pointY )
745 if ( weightB + weightC > 1 )
747 weightB = 1 - weightB;
748 weightC = 1 - weightC;
751 const double rBx = weightB * ( bX - aX );
752 const double rBy = weightB * ( bY - aY );
753 const double rCx = weightC * ( cX - aX );
754 const double rCy = weightC * ( cY - aY );
756 pointX = rBx + rCx + aX;
757 pointY = rBy + rCy + aY;
762 return qgsDoubleNear( x1 * ( y2 - y3 ) + x2 * ( y3 - y1 ) + x3 * ( y1 - y2 ), 0, epsilon );
768 const double cx = ( y2 - y1 ) * ( z3 - z1 ) - ( z2 - z1 ) * ( y3 - y1 );
769 const double cy = ( z2 - z1 ) * ( x3 - x1 ) - ( x2 - x1 ) * ( z3 - z1 );
770 const double cz = ( x2 - x1 ) * ( y3 - y1 ) - ( y2 - y1 ) * ( x3 - x1 );
773 return qgsDoubleNear( cx * cx + cy * cy + cz * cz, 0.0, epsilon * epsilon );
778 const double dx = x2 - x1;
779 const double dy = y2 - y1;
780 return ( std::atan2( dx, dy ) * 180.0 / M_PI );
784 double &pointX,
double &pointY,
double &angle )
786 angle = (
azimuth( aX, aY, bX, bY ) +
azimuth( cX, cY, dX, dY ) ) / 2.0;
788 bool intersection =
false;
789 QgsGeometryUtilsBase::segmentIntersection( aX, aY, bX, bY, cX, cY, dX, dY, pointX, pointY, intersection );
796 const double radsXy =
azimuth * M_PI / 180.0;
797 double dx = 0.0, dy = 0.0, dz = 0.0;
799 inclination = std::fmod( inclination, 360.0 );
801 if ( std::isnan( aZ ) &&
qgsDoubleNear( inclination, 90.0 ) )
803 dx = distance * std::sin( radsXy );
804 dy = distance * std::cos( radsXy );
808 const double radsZ = inclination * M_PI / 180.0;
809 dx = distance * std::sin( radsZ ) * std::sin( radsXy );
810 dy = distance * std::sin( radsZ ) * std::cos( radsXy );
811 dz = distance * std::cos( radsZ );
820 double &pointX,
double &pointY )
822 const double angle = (
azimuth( aX, aY, bX, bY ) +
azimuth( aX, aY, cX, cY ) ) / 2.0;
824 bool intersection =
false;
825 double dX = 0.0, dY = 0.0, dZ = 0.0;
826 project( aX, aY, std::numeric_limits<double>::quiet_NaN(), 1.0, angle, 90.0, dX, dY, dZ );
827 segmentIntersection( bX, bY, cX, cY, aX, aY, dX, dY, pointX, pointY, intersection );
834 const double segment2StartX,
const double segment2StartY,
const double segment2EndX,
const double segment2EndY,
837 double intersectionX, intersectionY;
840 segment1StartX, segment1StartY, segment1EndX, segment1EndY,
841 segment2StartX, segment2StartY, segment2EndX, segment2EndY,
842 intersectionX, intersectionY, isIntersection, epsilon,
true );
844 if ( !isIntersection )
854 const double dir1X = dist1ToStart > epsilon ? segment1StartX : segment1EndX;
855 const double dir1Y = dist1ToStart > epsilon ? segment1StartY : segment1EndY;
856 const double dir2X = dist2ToStart > epsilon ? segment2StartX : segment2EndX;
857 const double dir2Y = dist2ToStart > epsilon ? segment2StartY : segment2EndY;
861 intersectionX, intersectionY,
865 if ( std::abs( angle ) < epsilon || std::abs( angle - M_PI ) < epsilon )
870 double workingAngle = angle;
871 if ( workingAngle > M_PI )
873 workingAngle = 2 * M_PI - workingAngle;
876 const double halfAngle = workingAngle / 2.0;
877 if ( std::abs( std::sin( halfAngle ) ) < epsilon )
882 const double maxDist1 = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
883 const double maxDist2 = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
888 const bool intersectionOnSeg1 = std::abs( ( dist1ToStart + dist1ToEnd ) - seg1Length ) < epsilon;
889 const bool intersectionOnSeg2 = std::abs( ( dist2ToStart + dist2ToEnd ) - seg2Length ) < epsilon;
891 double maxDistanceToTangent = std::numeric_limits<double>::max();
893 if ( intersectionOnSeg1 )
895 maxDistanceToTangent = std::min( maxDistanceToTangent, maxDist1 - epsilon );
898 if ( intersectionOnSeg2 )
900 maxDistanceToTangent = std::min( maxDistanceToTangent, maxDist2 - epsilon );
903 if ( maxDistanceToTangent == std::numeric_limits<double>::max() )
905 maxDistanceToTangent = std::min( maxDist1, maxDist2 ) - epsilon;
908 if ( maxDistanceToTangent <= 0 )
913 return maxDistanceToTangent * std::tan( halfAngle );
917 const double segment1StartX,
const double segment1StartY,
const double segment1EndX,
const double segment1EndY,
918 const double segment2StartX,
const double segment2StartY,
const double segment2EndX,
const double segment2EndY,
920 double *filletPointsX,
double *filletPointsY,
921 double *trim1StartX,
double *trim1StartY,
922 double *trim1EndX,
double *trim1EndY,
923 double *trim2StartX,
double *trim2StartY,
924 double *trim2EndX,
double *trim2EndY,
925 const double epsilon )
931 double intersectionX, intersectionY;
934 segment1StartX, segment1StartY, segment1EndX, segment1EndY,
935 segment2StartX, segment2StartY, segment2EndX, segment2EndY,
936 intersectionX, intersectionY, isIntersection, epsilon,
true );
938 if ( !isIntersection )
951 const double dir1X = dist1ToStart > epsilon ? segment1StartX : segment1EndX;
952 const double dir1Y = dist1ToStart > epsilon ? segment1StartY : segment1EndY;
953 const double dir2X = dist2ToStart > epsilon ? segment2StartX : segment2EndX;
954 const double dir2Y = dist2ToStart > epsilon ? segment2StartY : segment2EndY;
959 intersectionX, intersectionY,
964 if ( std::abs( angle ) < epsilon || std::abs( angle - M_PI ) < epsilon )
970 double workingAngle = angle;
971 if ( workingAngle > M_PI )
973 workingAngle = 2 * M_PI - workingAngle;
976 const double halfAngle = workingAngle / 2.0;
977 if ( std::abs( std::sin( halfAngle ) ) < epsilon )
984 const double distanceToTangent = radius / std::tan( halfAngle );
986 const double maxDist1 = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
987 const double maxDist2 = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
993 const bool intersectionOnSeg1 = std::abs( ( dist1ToStart + dist1ToEnd ) - seg1Length ) < epsilon;
994 const bool intersectionOnSeg2 = std::abs( ( dist2ToStart + dist2ToEnd ) - seg2Length ) < epsilon;
998 if ( intersectionOnSeg1 && distanceToTangent > maxDist1 - epsilon )
1003 if ( intersectionOnSeg2 && distanceToTangent > maxDist2 - epsilon )
1009 double T1x, T1y, T2x, T2y;
1011 intersectionX, intersectionY,
1013 distanceToTangent, T1x, T1y
1016 intersectionX, intersectionY,
1018 distanceToTangent, T2x, T2y
1022 const QgsVector v1( dir1X - intersectionX, dir1Y - intersectionY );
1023 const QgsVector v2( dir2X - intersectionX, dir2Y - intersectionY );
1029 const double centerDistance = radius / std::sin( halfAngle );
1030 const double centerX = intersectionX + bisectorDirection.
x() * centerDistance;
1031 const double centerY = intersectionY + bisectorDirection.
y() * centerDistance;
1036 const QgsVector midDirection = ( centerToT1 + centerToT2 ).normalized();
1038 const double midX = centerX + midDirection.
x() * radius;
1039 const double midY = centerY + midDirection.
y() * radius;
1042 filletPointsX[0] = T1x;
1043 filletPointsY[0] = T1y;
1044 filletPointsX[1] = midX;
1045 filletPointsY[1] = midY;
1046 filletPointsX[2] = T2x;
1047 filletPointsY[2] = T2y;
1052 if ( dist1ToStart > epsilon )
1054 *trim1StartX = segment1StartX;
1055 *trim1StartY = segment1StartY;
1059 *trim1StartX = segment1EndX;
1060 *trim1StartY = segment1EndY;
1067 if ( dist2ToStart > epsilon )
1069 *trim2StartX = segment2StartX;
1070 *trim2StartY = segment2StartY;
1074 *trim2StartX = segment2EndX;
1075 *trim2StartY = segment2EndY;
1085 const double segment1StartX,
const double segment1StartY,
const double segment1EndX,
const double segment1EndY,
1086 const double segment2StartX,
const double segment2StartY,
const double segment2EndX,
const double segment2EndY,
1087 double distance1,
double distance2,
1088 double &chamferStartX,
double &chamferStartY,
1089 double &chamferEndX,
double &chamferEndY,
1090 double *trim1StartX,
double *trim1StartY,
1091 double *trim1EndX,
double *trim1EndY,
1092 double *trim2StartX,
double *trim2StartY,
1093 double *trim2EndX,
double *trim2EndY,
1094 const double epsilon )
1097 if ( distance2 <= 0 )
1098 distance2 = distance1;
1101 if ( distance1 <= 0 || distance2 <= 0 )
1105 double intersectionX, intersectionY;
1106 bool isIntersection;
1108 segment1StartX, segment1StartY, segment1EndX, segment1EndY,
1109 segment2StartX, segment2StartY, segment2EndX, segment2EndY,
1110 intersectionX, intersectionY, isIntersection, epsilon,
true );
1112 if ( !isIntersection )
1118 if ( distance2 < 0 )
1119 distance2 = distance1;
1130 if ( dist1ToStart > epsilon )
1133 intersectionX, intersectionY,
1134 segment1StartX, segment1StartY,
1141 intersectionX, intersectionY,
1142 segment1EndX, segment1EndY,
1148 if ( dist2ToStart > epsilon )
1151 intersectionX, intersectionY,
1152 segment2StartX, segment2StartY,
1159 intersectionX, intersectionY,
1160 segment2EndX, segment2EndY,
1166 const double distToSeg1Target = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
1167 const double distToSeg2Target = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
1169 if ( distance1 > distToSeg1Target - epsilon )
1171 if ( dist1ToStart > epsilon )
1174 intersectionX, intersectionY,
1175 segment1StartX, segment1StartY,
1176 distToSeg1Target, T1x, T1y
1182 intersectionX, intersectionY,
1183 segment1EndX, segment1EndY,
1184 distToSeg1Target, T1x, T1y
1189 if ( distance2 > distToSeg2Target - epsilon )
1191 if ( dist2ToStart > epsilon )
1194 intersectionX, intersectionY,
1195 segment2StartX, segment2StartY,
1196 distToSeg2Target, T2x, T2y
1202 intersectionX, intersectionY,
1203 segment2EndX, segment2EndY,
1204 distToSeg2Target, T2x, T2y
1209 chamferStartX = T1x;
1210 chamferStartY = T1y;
1217 if ( dist1ToStart > epsilon )
1219 *trim1StartX = segment1StartX; *trim1StartY = segment1StartY;
1220 *trim1EndX = T1x; *trim1EndY = T1y;
1224 *trim1StartX = segment1EndX; *trim1StartY = segment1EndY;
1225 *trim1EndX = T1x; *trim1EndY = T1y;
1230 if ( dist2ToStart > epsilon )
1232 *trim2StartX = segment2StartX; *trim2StartY = segment2StartY;
1233 *trim2EndX = T2x; *trim2EndY = T2y;
1237 *trim2StartX = segment2EndX; *trim2StartY = segment2EndY;
1238 *trim2EndX = T2x; *trim2EndY = T2y;
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).