I have a string of coordinates, read from a JSON file, which belongs to a certain ROI, drawn by the user of an application. I am supposed to eventually determine if the coordinates represent a polygon or an ellipse (AKA did the user paint a polygon or an ellipse). I have a serious problem of figuring out the correct algorithm, since it is also a math-related problem. The code have written so far, recognizes an ellipse, but then considers a polygon also an ellipse. My initial idea was to put all the coords inside the ellipse equation and check if it matches the characteristics of an ellipse. But somehow I fail to differentiate it from the polygon.
Example for the format of the coordinates that I retrieve from the JSON file:
Ellipse coordinates:
M/322.504/80.6014;L/322.3/84.7773;L/321.684/88.899;L/319.253/96.9595;L/315.292/104.742;L/309.881/112.205;L/303.102/119.309;L/295.036/126.012;L/285.763/132.273;L/275.364/138.052;L/263.921/143.307;L/251.515/147.997;L/238.226/152.082;L/224.136/155.521;L/209.325/158.273;L/193.875/160.297;L/177.866/161.551;L/161.38/161.996;L/144.892/161.603;L/128.88/160.399;L/113.423/158.423;L/98.6038/155.718;L/84.5029/152.323;L/71.2013/148.28;L/58.7804/143.628;L/47.3212/138.409;L/36.9047/132.663;L/27.6122/126.431;L/19.5247/119.753;L/12.7234/112.671;L/7.28933/105.224;L/3.30368/97.4543;L/0.847538/89.4014;L/0.218384/85.2816;L/0.00202717/81.1064;L/0.205307/76.9305;L/0.821556/72.8088;L/3.25246/64.7483;L/7.21376/56.9658;L/12.6245/49.5023;L/19.4036/42.3987;L/27.4701/35.6959;L/36.7431/29.4347;L/47.1415/23.6562;L/58.5843/18.4012;L/70.9906/13.7107;L/84.2794/9.62544;L/98.3697/6.1865;L/113.18/3.43473;L/128.631/1.41106;L/144.639/0.156398;L/161.126/-0.288348;L/177.613/0.104763;L/193.626/1.30929;L/209.083/3.28456;L/223.902/5.98993;L/238.003/9.38472;L/251.304/13.4283;L/263.725/18.08;L/275.185/23.2991;L/285.601/29.045;L/294.894/35.2771;L/302.981/41.9547;L/309.782/49.037;L/315.216/56.4835;L/319.202/64.2535;L/321.658/72.3064;L/322.287/76.4262;L/322.504/80.6014
Polygon coordinates:
M/0.0102565/69.1651;L/19.019/51.4713;L/19.6427/5.25438;L/111.389/0.385824;L/112.778/24.1719;L/288.807/24.6385;L/288.255/129.985;L/242.72/131.399;L/221.009/162.01;L/138.096/166.188;L/116.982/128.833;L/113.55/100.971;L/65.9781/103.747;L/48.9573/79.3007;L/1.3638/64.406
So, the program is supposed to determine that the first set of coordinates belong to an ellipse, and the second one to a polygon.
Note: the number of coordinates are never the same, since it is fully up to the user, how the polygon should look like, therefore it is not safe to say that the length of the coordinates from a polygon will also be fewer than an ellipse.
I thank you guys in advance and hope to be able to find a solution for this problem.
My current code:
#include <iostream>
#include <vector>
#include <sstream>
#include <cmath>
// Structure to hold coordinate data
struct Coordinate {
double x;
double y;
};
// Function to check if coordinates satisfy the ellipse equation
bool isEllipse(const std::vector<Coordinate>& coordinates) {
// Number of coordinates
int numPoints = coordinates.size();
// Calculate the centroid
double sumX = 0.0, sumY = 0.0;
for (const auto& coord : coordinates) {
sumX += coord.x;
sumY += coord.y;
}
double centerX = sumX / numPoints;
double centerY = sumY / numPoints;
// Calculate the major and minor axes
double maxDistSqr = 0.0;
for (const auto& coord : coordinates) {
double dx = coord.x - centerX;
double dy = coord.y - centerY;
double distSqr = dx * dx + dy * dy;
if (distSqr > maxDistSqr) {
maxDistSqr = distSqr;
}
}
double a = std::sqrt(maxDistSqr);
double b = std::sqrt(maxDistSqr);
// Check if the coordinates satisfy the ellipse equation
for (const auto& coord : coordinates) {
double dx = coord.x - centerX;
double dy = coord.y - centerY;
double ellipseResult = (dx * dx) / (a * a) + (dy * dy) / (b * b);
if (ellipseResult > 1.0) {
return false;
}
}
return true;
}
int main() {
std::string coordinatesStr = "M/-0.247283/512.418;L/166.935/505.209;L/175.478/415.698;L/141.124/384.968;L/207.244/354.6;L/211.621/292.758;L/269.472/283.712;L/259.446/10.8997;L/773.612/-0.156929;L/773.644/277.548;L/850.632/280.289;L/850.638/335.28;L/927.629/368.266;L/886.392/423.262;L/894.646/470.004;L/1007.98/479.435;L/1015.16/565.507;L/20.5376/572.793;L/-0.0663959/512.529;L/0.189167/513.04";
std::vector<Coordinate> coordinates;
// Parse the coordinate string
std::istringstream iss(coordinatesStr);
std::string segment;
while (std::getline(iss, segment, ';')) {
// Parse M or L coordinates
if (segment[0] == 'M' || segment[0] == 'L') {
std::istringstream coordIss(segment.substr(2));
std::string xStr, yStr;
if (std::getline(coordIss, xStr, '/') && std::getline(coordIss, yStr, '/')) {
try {
double x = std::stod(xStr);
double y = std::stod(yStr);
coordinates.push_back({ x, y });
} catch (const std::invalid_argument& e) {
std::cerr << "Failed to parse coordinate: " << segment << std::endl;
}
}
}
}
// Check if the coordinates satisfy the ellipse equation
bool isAnEllipse = isEllipse(coordinates);
if (isAnEllipse) {
std::cout << "The coordinates form an ellipse." << std::endl;
} else {
std::cout << "The coordinates do not form an ellipse." << std::endl;
}
return 0;
}