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;
577static bool equals(
double p1x,
double p1y,
double p2x,
double p2y,
double epsilon = 1e-8 )
582bool 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 )
584 isIntersection =
false;
585 intersectionPointX = intersectionPointY = std::numeric_limits<double>::quiet_NaN();
589 const double vl = v.
length();
590 const double wl = w.
length();
599 if ( !
lineIntersection( p1x, p1y, v, q1x, q1y, w, intersectionPointX, intersectionPointY ) )
604 isIntersection =
true;
605 if ( acceptImproperIntersection )
607 if ( ( equals( p1x, p1y, q1x, q1y ) ) || ( equals( p1x, p1y, q2x, q2y ) ) )
609 intersectionPointX = p1x;
610 intersectionPointY = p1y;
613 else if ( ( equals( p1x, p1y, q2x, q2y ) ) || ( equals( p2x, p2y, q2x, q2y ) ) )
615 intersectionPointX = p2x;
616 intersectionPointY = p2y;
623 qgsDoubleNear(
sqrDistToLine( p1x, p1y, q1x, q1y, q2x, q2y, x, y, tolerance ), 0.0, tolerance ) ||
625 qgsDoubleNear(
sqrDistToLine( p2x, p2y, q1x, q1y, q2x, q2y, x, y, tolerance ), 0.0, tolerance ) ||
627 qgsDoubleNear(
sqrDistToLine( q1x, q1y, p1x, p1y, p2x, p2y, x, y, tolerance ), 0.0, tolerance ) ||
629 qgsDoubleNear(
sqrDistToLine( q2x, q2y, p1x, p1y, p2x, p2y, x, y, tolerance ), 0.0, tolerance )
636 const double lambdav =
QgsVector( intersectionPointX - p1x, intersectionPointY - p1y ) * v;
637 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
640 const double lambdaw =
QgsVector( intersectionPointX - q1x, intersectionPointY - q1y ) * w;
641 return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
655 double ptInterX = 0.0, ptInterY = 0.0;
656 bool isIntersection =
false;
665 intersection.
set( ptInterX, ptInterY, La1.
z() );
705 if ( !firstIsDone || !secondIsDone )
711 intersection = ( X1 + X2 ) / 2.0;
717 return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
722 const double dxp = px - x1;
723 const double dyp = py - y1;
725 const double dxl = x2 - x1;
726 const double dyl = y2 - y1;
728 return std::sqrt( ( dxp * dxp ) + ( dyp * dyp ) ) / std::sqrt( ( dxl * dxl ) + ( dyl * dyl ) );
732 double weightB,
double weightC,
double &pointX,
double &pointY )
735 if ( weightB + weightC > 1 )
737 weightB = 1 - weightB;
738 weightC = 1 - weightC;
741 const double rBx = weightB * ( bX - aX );
742 const double rBy = weightB * ( bY - aY );
743 const double rCx = weightC * ( cX - aX );
744 const double rCy = weightC * ( cY - aY );
746 pointX = rBx + rCx + aX;
747 pointY = rBy + rCy + aY;
752 return qgsDoubleNear( x1 * ( y2 - y3 ) + x2 * ( y3 - y1 ) + x3 * ( y1 - y2 ), 0, epsilon );
758 const double cx = ( y2 - y1 ) * ( z3 - z1 ) - ( z2 - z1 ) * ( y3 - y1 );
759 const double cy = ( z2 - z1 ) * ( x3 - x1 ) - ( x2 - x1 ) * ( z3 - z1 );
760 const double cz = ( x2 - x1 ) * ( y3 - y1 ) - ( y2 - y1 ) * ( x3 - x1 );
763 return qgsDoubleNear( cx * cx + cy * cy + cz * cz, 0.0, epsilon * epsilon );
768 const double dx = x2 - x1;
769 const double dy = y2 - y1;
770 return ( std::atan2( dx, dy ) * 180.0 / M_PI );
774 double &pointX,
double &pointY,
double &angle )
776 angle = (
azimuth( aX, aY, bX, bY ) +
azimuth( cX, cY, dX, dY ) ) / 2.0;
778 bool intersection =
false;
779 QgsGeometryUtilsBase::segmentIntersection( aX, aY, bX, bY, cX, cY, dX, dY, pointX, pointY, intersection );
786 const double radsXy =
azimuth * M_PI / 180.0;
787 double dx = 0.0, dy = 0.0, dz = 0.0;
789 inclination = std::fmod( inclination, 360.0 );
791 if ( std::isnan( aZ ) &&
qgsDoubleNear( inclination, 90.0 ) )
793 dx = distance * std::sin( radsXy );
794 dy = distance * std::cos( radsXy );
798 const double radsZ = inclination * M_PI / 180.0;
799 dx = distance * std::sin( radsZ ) * std::sin( radsXy );
800 dy = distance * std::sin( radsZ ) * std::cos( radsXy );
801 dz = distance * std::cos( radsZ );
810 double &pointX,
double &pointY )
812 const double angle = (
azimuth( aX, aY, bX, bY ) +
azimuth( aX, aY, cX, cY ) ) / 2.0;
814 bool intersection =
false;
815 double dX = 0.0, dY = 0.0, dZ = 0.0;
816 project( aX, aY, std::numeric_limits<double>::quiet_NaN(), 1.0, angle, 90.0, dX, dY, dZ );
817 segmentIntersection( bX, bY, cX, cY, aX, aY, dX, dY, pointX, pointY, intersection );
824 const double segment2StartX,
const double segment2StartY,
const double segment2EndX,
const double segment2EndY,
827 double intersectionX, intersectionY;
830 segment1StartX, segment1StartY, segment1EndX, segment1EndY,
831 segment2StartX, segment2StartY, segment2EndX, segment2EndY,
832 intersectionX, intersectionY, isIntersection, epsilon,
true );
834 if ( !isIntersection )
844 const double dir1X = dist1ToStart > epsilon ? segment1StartX : segment1EndX;
845 const double dir1Y = dist1ToStart > epsilon ? segment1StartY : segment1EndY;
846 const double dir2X = dist2ToStart > epsilon ? segment2StartX : segment2EndX;
847 const double dir2Y = dist2ToStart > epsilon ? segment2StartY : segment2EndY;
851 intersectionX, intersectionY,
855 if ( std::abs( angle ) < epsilon || std::abs( angle - M_PI ) < epsilon )
860 double workingAngle = angle;
861 if ( workingAngle > M_PI )
863 workingAngle = 2 * M_PI - workingAngle;
866 const double halfAngle = workingAngle / 2.0;
867 if ( std::abs( std::sin( halfAngle ) ) < epsilon )
872 const double maxDist1 = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
873 const double maxDist2 = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
878 const bool intersectionOnSeg1 = std::abs( ( dist1ToStart + dist1ToEnd ) - seg1Length ) < epsilon;
879 const bool intersectionOnSeg2 = std::abs( ( dist2ToStart + dist2ToEnd ) - seg2Length ) < epsilon;
881 double maxDistanceToTangent = std::numeric_limits<double>::max();
883 if ( intersectionOnSeg1 )
885 maxDistanceToTangent = std::min( maxDistanceToTangent, maxDist1 - epsilon );
888 if ( intersectionOnSeg2 )
890 maxDistanceToTangent = std::min( maxDistanceToTangent, maxDist2 - epsilon );
893 if ( maxDistanceToTangent == std::numeric_limits<double>::max() )
895 maxDistanceToTangent = std::min( maxDist1, maxDist2 ) - epsilon;
898 if ( maxDistanceToTangent <= 0 )
903 return maxDistanceToTangent * std::tan( halfAngle );
907 const double segment1StartX,
const double segment1StartY,
const double segment1EndX,
const double segment1EndY,
908 const double segment2StartX,
const double segment2StartY,
const double segment2EndX,
const double segment2EndY,
910 double *filletPointsX,
double *filletPointsY,
911 double *trim1StartX,
double *trim1StartY,
912 double *trim1EndX,
double *trim1EndY,
913 double *trim2StartX,
double *trim2StartY,
914 double *trim2EndX,
double *trim2EndY,
915 const double epsilon )
921 double intersectionX, intersectionY;
924 segment1StartX, segment1StartY, segment1EndX, segment1EndY,
925 segment2StartX, segment2StartY, segment2EndX, segment2EndY,
926 intersectionX, intersectionY, isIntersection, epsilon,
true );
928 if ( !isIntersection )
941 const double dir1X = dist1ToStart > epsilon ? segment1StartX : segment1EndX;
942 const double dir1Y = dist1ToStart > epsilon ? segment1StartY : segment1EndY;
943 const double dir2X = dist2ToStart > epsilon ? segment2StartX : segment2EndX;
944 const double dir2Y = dist2ToStart > epsilon ? segment2StartY : segment2EndY;
949 intersectionX, intersectionY,
954 if ( std::abs( angle ) < epsilon || std::abs( angle - M_PI ) < epsilon )
960 double workingAngle = angle;
961 if ( workingAngle > M_PI )
963 workingAngle = 2 * M_PI - workingAngle;
966 const double halfAngle = workingAngle / 2.0;
967 if ( std::abs( std::sin( halfAngle ) ) < epsilon )
974 const double distanceToTangent = radius / std::tan( halfAngle );
976 const double maxDist1 = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
977 const double maxDist2 = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
983 const bool intersectionOnSeg1 = std::abs( ( dist1ToStart + dist1ToEnd ) - seg1Length ) < epsilon;
984 const bool intersectionOnSeg2 = std::abs( ( dist2ToStart + dist2ToEnd ) - seg2Length ) < epsilon;
988 if ( intersectionOnSeg1 && distanceToTangent > maxDist1 - epsilon )
993 if ( intersectionOnSeg2 && distanceToTangent > maxDist2 - epsilon )
999 double T1x, T1y, T2x, T2y;
1001 intersectionX, intersectionY,
1003 distanceToTangent, T1x, T1y
1006 intersectionX, intersectionY,
1008 distanceToTangent, T2x, T2y
1012 const QgsVector v1( dir1X - intersectionX, dir1Y - intersectionY );
1013 const QgsVector v2( dir2X - intersectionX, dir2Y - intersectionY );
1019 const double centerDistance = radius / std::sin( halfAngle );
1020 const double centerX = intersectionX + bisectorDirection.
x() * centerDistance;
1021 const double centerY = intersectionY + bisectorDirection.
y() * centerDistance;
1026 const QgsVector midDirection = ( centerToT1 + centerToT2 ).normalized();
1028 const double midX = centerX + midDirection.
x() * radius;
1029 const double midY = centerY + midDirection.
y() * radius;
1032 filletPointsX[0] = T1x;
1033 filletPointsY[0] = T1y;
1034 filletPointsX[1] = midX;
1035 filletPointsY[1] = midY;
1036 filletPointsX[2] = T2x;
1037 filletPointsY[2] = T2y;
1042 if ( dist1ToStart > epsilon )
1044 *trim1StartX = segment1StartX;
1045 *trim1StartY = segment1StartY;
1049 *trim1StartX = segment1EndX;
1050 *trim1StartY = segment1EndY;
1057 if ( dist2ToStart > epsilon )
1059 *trim2StartX = segment2StartX;
1060 *trim2StartY = segment2StartY;
1064 *trim2StartX = segment2EndX;
1065 *trim2StartY = segment2EndY;
1075 const double segment1StartX,
const double segment1StartY,
const double segment1EndX,
const double segment1EndY,
1076 const double segment2StartX,
const double segment2StartY,
const double segment2EndX,
const double segment2EndY,
1077 double distance1,
double distance2,
1078 double &chamferStartX,
double &chamferStartY,
1079 double &chamferEndX,
double &chamferEndY,
1080 double *trim1StartX,
double *trim1StartY,
1081 double *trim1EndX,
double *trim1EndY,
1082 double *trim2StartX,
double *trim2StartY,
1083 double *trim2EndX,
double *trim2EndY,
1084 const double epsilon )
1087 if ( distance2 <= 0 )
1088 distance2 = distance1;
1091 if ( distance1 <= 0 || distance2 <= 0 )
1095 double intersectionX, intersectionY;
1096 bool isIntersection;
1098 segment1StartX, segment1StartY, segment1EndX, segment1EndY,
1099 segment2StartX, segment2StartY, segment2EndX, segment2EndY,
1100 intersectionX, intersectionY, isIntersection, epsilon,
true );
1102 if ( !isIntersection )
1108 if ( distance2 < 0 )
1109 distance2 = distance1;
1120 if ( dist1ToStart > epsilon )
1123 intersectionX, intersectionY,
1124 segment1StartX, segment1StartY,
1131 intersectionX, intersectionY,
1132 segment1EndX, segment1EndY,
1138 if ( dist2ToStart > epsilon )
1141 intersectionX, intersectionY,
1142 segment2StartX, segment2StartY,
1149 intersectionX, intersectionY,
1150 segment2EndX, segment2EndY,
1156 const double distToSeg1Target = ( dist1ToStart > epsilon ) ? dist1ToStart : dist1ToEnd;
1157 const double distToSeg2Target = ( dist2ToStart > epsilon ) ? dist2ToStart : dist2ToEnd;
1159 if ( distance1 > distToSeg1Target - epsilon )
1161 if ( dist1ToStart > epsilon )
1164 intersectionX, intersectionY,
1165 segment1StartX, segment1StartY,
1166 distToSeg1Target, T1x, T1y
1172 intersectionX, intersectionY,
1173 segment1EndX, segment1EndY,
1174 distToSeg1Target, T1x, T1y
1179 if ( distance2 > distToSeg2Target - epsilon )
1181 if ( dist2ToStart > epsilon )
1184 intersectionX, intersectionY,
1185 segment2StartX, segment2StartY,
1186 distToSeg2Target, T2x, T2y
1192 intersectionX, intersectionY,
1193 segment2EndX, segment2EndY,
1194 distToSeg2Target, T2x, T2y
1199 chamferStartX = T1x;
1200 chamferStartY = T1y;
1207 if ( dist1ToStart > epsilon )
1209 *trim1StartX = segment1StartX; *trim1StartY = segment1StartY;
1210 *trim1EndX = T1x; *trim1EndY = T1y;
1214 *trim1StartX = segment1EndX; *trim1StartY = segment1EndY;
1215 *trim1EndX = T1x; *trim1EndY = T1y;
1220 if ( dist2ToStart > epsilon )
1222 *trim2StartX = segment2StartX; *trim2StartY = segment2StartY;
1223 *trim2EndX = T2x; *trim2EndY = T2y;
1227 *trim2StartX = segment2EndX; *trim2StartY = segment2EndY;
1228 *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 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 double maxFilletRadius(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 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).