! \internal \a a, \a b and \a c are corner points of an equilateral triangle. (\a x,\a y) is an arbitrary point inside or outside this triangle. If (x,y) is inside the triangle, this function returns the double point (x,y). Otherwise, the intersection of the perpendicular projection of (x,y) onto the closest triangle edge is returned, unless this intersection is outs
| 1095 | Yes, it's trigonometry. |
| 1096 | */ |
| 1097 | QPointF QtColorTriangle::movePointToTriangle(double x, double y, const Vertex &a, |
| 1098 | const Vertex &b, const Vertex &c) const |
| 1099 | { |
| 1100 | // Let v1A be the vector from (x,y) to a. |
| 1101 | // Let v2A be the vector from a to b. |
| 1102 | // Find the angle alphaA between v1A and v2A. |
| 1103 | double v1xA = x - a.point.x(); |
| 1104 | double v1yA = y - a.point.y(); |
| 1105 | double v2xA = b.point.x() - a.point.x(); |
| 1106 | double v2yA = b.point.y() - a.point.y(); |
| 1107 | double vpA = vprod(v1xA, v1yA, v2xA, v2yA); |
| 1108 | double cosA = vpA / (vlen(v1xA, v1yA) * vlen(v2xA, v2yA)); |
| 1109 | double alphaA = acos(cosA); |
| 1110 | |
| 1111 | // Let v1B be the vector from x to b. |
| 1112 | // Let v2B be the vector from b to c. |
| 1113 | double v1xB = x - b.point.x(); |
| 1114 | double v1yB = y - b.point.y(); |
| 1115 | double v2xB = c.point.x() - b.point.x(); |
| 1116 | double v2yB = c.point.y() - b.point.y(); |
| 1117 | double vpB = vprod(v1xB, v1yB, v2xB, v2yB); |
| 1118 | double cosB = vpB / (vlen(v1xB, v1yB) * vlen(v2xB, v2yB)); |
| 1119 | double alphaB = acos(cosB); |
| 1120 | |
| 1121 | // Let v1C be the vector from x to c. |
| 1122 | // Let v2C be the vector from c back to a. |
| 1123 | double v1xC = x - c.point.x(); |
| 1124 | double v1yC = y - c.point.y(); |
| 1125 | double v2xC = a.point.x() - c.point.x(); |
| 1126 | double v2yC = a.point.y() - c.point.y(); |
| 1127 | double vpC = vprod(v1xC, v1yC, v2xC, v2yC); |
| 1128 | double cosC = vpC / (vlen(v1xC, v1yC) * vlen(v2xC, v2yC)); |
| 1129 | double alphaC = acos(cosC); |
| 1130 | |
| 1131 | // Find the radian angles between the (1,0) vector and the points |
| 1132 | // A, B, C and (x,y). Use this information to determine which of |
| 1133 | // the edges we should project (x,y) onto. |
| 1134 | double angleA = angleAt(a.point, contentsRect()); |
| 1135 | double angleB = angleAt(b.point, contentsRect()); |
| 1136 | double angleC = angleAt(c.point, contentsRect()); |
| 1137 | double angleP = angleAt(QPointF(x, y), contentsRect()); |
| 1138 | |
| 1139 | // If (x,y) is in the a-b area, project onto the a-b vector. |
| 1140 | if (angleBetweenAngles(angleP, angleA, angleB)) { |
| 1141 | // Find the distance from (x,y) to a. Then use the slope of |
| 1142 | // the a-b vector with this distance and the angle between a-b |
| 1143 | // and a-(x,y) to determine the point of intersection of the |
| 1144 | // perpendicular projection from (x,y) onto a-b. |
| 1145 | double pdist = sqrt(qsqr(x - a.point.x()) + qsqr(y - a.point.y())); |
| 1146 | |
| 1147 | // the length of all edges is always > 0 |
| 1148 | double p0x = a.point.x() + ((b.point.x() - a.point.x()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist; |
| 1149 | double p0y = a.point.y() + ((b.point.y() - a.point.y()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist; |
| 1150 | |
| 1151 | // If (x,y) is above the a-b line, which basically means it's |
| 1152 | // outside the triangle, then return its projection onto a-b. |
| 1153 | if (pointAbovePoint(x, y, p0x, p0y, a.point.x(), a.point.y(), b.point.x(), b.point.y())) { |
| 1154 | // If the projection is "outside" a, return a. If it is |
nothing calls this directly
no test coverage detected