Hello I am looking for a function with this header :
double drawArc(cv::Mat& image, const cv::Point& pointA, const cv::Point& pointB, const cv::Point& pointC, const cv::Scalar& color, int thickness);
which draw a circle arc beginning at point A, ending at point B and passing at point C
it return the arc angle in degrees
I have asking chatGPT but it fails to find a solution.
Thank you very much
Best regards
finally after fighting 4 hours with chatGPT 4 I obtained the following code which seems to work :
double drawArc(cv::Mat& image, const cv::Point& pointA, const cv::Point& pointB, const cv::Point& pointC, const cv::Scalar& color, int thickness) {
// Calculer le centre du cercle passant par les trois points
double ax = pointA.x, ay = pointA.y;
double bx = pointB.x, by = pointB.y;
double cx = pointC.x, cy = pointC.y;
double d = 2.0 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));
double ux = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d;
double uy = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d;
cv::Point center(ux, uy);
// Calculer le rayon du cercle
double radius = std::hypot(pointA.x - center.x, pointA.y - center.y);
// Calculer les angles des points par rapport au centre du cercle
double angleA = std::atan2(pointA.y - center.y, pointA.x - center.x) * 180 / CV_PI;
double angleB = std::atan2(pointB.y - center.y, pointB.x - center.x) * 180 / CV_PI;
double angleC = std::atan2(pointC.y - center.y, pointC.x - center.x) * 180 / CV_PI;
// Ajuster les angles si nécessaire
if (angleA < 0) angleA += 360;
if (angleB < 0) angleB += 360;
if (angleC < 0) angleC += 360;
// Déterminer l'angle de début et de fin pour le dessin
double startAngle, endAngle;
// Organiser les angles dans l'ordre croissant
std::vector<double> angles = { angleA, angleB, angleC };
std::sort(angles.begin(), angles.end());
// Si l'angle de C est l'angle intermédiaire, alors C est entre A et B
if (angles[1] == angleC) {
startAngle = angleA;
endAngle = angleB;
}
else {
// Si non, dessiner l'arc complémentaire
if (angleA > angleB) {
startAngle = angleA;
endAngle = angleB + 360;
}
else {
startAngle = angleA + 360;
endAngle = angleB;
}
}
// Dessiner l'arc
cv::ellipse(image, center, cv::Size(radius, radius), 0, startAngle, endAngle, color, thickness);
// Calculer et retourner l'angle de l'arc
double arcAngle = endAngle - startAngle;
if (arcAngle < 0) arcAngle += 360;
return arcAngle;
}
since OpenCV does not have a "fitCircle"
(only fitEllipse
), this would require solving for the circle parameters manually:
OK thank you but what I wanted was not simply draw a circle passing by 3 points but an arc beginning at A, ending at B and passing at C
but the code of chatGPT works