MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / arcTo

Method arcTo

app/src/UI/Widgets/PainterContext.cpp:1041–1108  ·  view source on GitHub ↗

* @brief Adds a Canvas2D-style arcTo: tangent arc of radius r between two segments. */

Source from the content-addressed store, hash-verified

1039 * @brief Adds a Canvas2D-style arcTo: tangent arc of radius r between two segments.
1040 */
1041void Widgets::PainterContext::arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal r)
1042{
1043 if (r < 0.0)
1044 return;
1045
1046 if (m_path.isEmpty()) {
1047 m_path.moveTo(x1, y1);
1048 return;
1049 }
1050
1051 const QPointF p0 = m_path.currentPosition();
1052 const qreal v1x = p0.x() - x1;
1053 const qreal v1y = p0.y() - y1;
1054 const qreal v2x = x2 - x1;
1055 const qreal v2y = y2 - y1;
1056 const qreal len1 = std::hypot(v1x, v1y);
1057 const qreal len2 = std::hypot(v2x, v2y);
1058 if (qFuzzyIsNull(len1) || qFuzzyIsNull(len2) || qFuzzyIsNull(r)) {
1059 m_path.lineTo(x1, y1);
1060 return;
1061 }
1062
1063 const qreal cos_a = (v1x * v2x + v1y * v2y) / (len1 * len2);
1064 const qreal a = std::acos(qBound<qreal>(-1.0, cos_a, 1.0));
1065 if (qFuzzyCompare(a, M_PI) || qFuzzyIsNull(a)) {
1066 m_path.lineTo(x1, y1);
1067 return;
1068 }
1069
1070 const qreal d = r / std::tan(a * 0.5);
1071 const qreal invLen1 = 1.0 / len1;
1072 const qreal invLen2 = 1.0 / len2;
1073 const qreal n1x = v1x * invLen1;
1074 const qreal n1y = v1y * invLen1;
1075 const qreal n2x = v2x * invLen2;
1076 const qreal n2y = v2y * invLen2;
1077 const qreal tx1 = x1 + n1x * d;
1078 const qreal ty1 = y1 + n1y * d;
1079 const qreal tx2 = x1 + n2x * d;
1080 const qreal ty2 = y1 + n2y * d;
1081
1082 const qreal sx = n1x + n2x;
1083 const qreal sy = n1y + n2y;
1084 const qreal sl = std::hypot(sx, sy);
1085 if (qFuzzyIsNull(sl)) {
1086 m_path.lineTo(x1, y1);
1087 return;
1088 }
1089
1090 const qreal cR = r / std::sin(a * 0.5);
1091 const qreal invSl = 1.0 / sl;
1092 const qreal cX = x1 + (sx * invSl) * cR;
1093 const qreal cY = y1 + (sy * invSl) * cR;
1094 const qreal cross = v1x * v2y - v1y * v2x;
1095
1096 m_path.lineTo(tx1, ty1);
1097
1098 const qreal startAng = std::atan2(ty1 - cY, tx1 - cX);

Callers 3

roundRectMethod · 0.80
arcMethod · 0.80
ellipseMethod · 0.80

Calls 9

hypotFunction · 0.85
acosFunction · 0.85
tanFunction · 0.85
sinFunction · 0.85
atan2Function · 0.85
isEmptyMethod · 0.80
moveToMethod · 0.80
xMethod · 0.80
lineToMethod · 0.80

Tested by

no test coverage detected