function get_projection_on_circumference(point) {
var angle = point_direction(center_x, center_y, point.x, point.y);
return new Point(
center_x + radius * cos(angle),
center_y + radius * sin(angle),
);
}
function get_score(points) {
static max_error = 100;
var n_points = array_length(points);
// error: distance from circumference
var dis_error = 0;
for (var i = 0; i < n_points; ++i) {
var point = points[i];
var dis = distance(center_x, center_y, point.x, point.y);
dis_error += sqr(radius - dis);
}
dis_error /= n_points;
dis_error = sqrt(dis_error);
// project points on the circumference
for (var i = 0; i < n_points; ++i) {
points[i] = get_projection_on_circumference(points[i]);
}
// sort "points" in anti-clockwise order
array_sort(points, function(p1, p2) {
var dir1 = point_direction(center_x, center_y, p1.x, p1.y);
var dir2 = point_direction(center_x, center_y, p2.x, p2.y);
return ((dir1 < dir2) ? -1 : 1);
});
// error: evenly spaced
var space_error = 0;
var expected_angle = 360 / n_points;
var j = n_points-1;
for (var i = 0; i < n_points; ++i) {
var p1 = points[j];
var p2 = points[i];
var dis = distance(p1.x, p1.y, p2.x, p2.y);
var _val = clamp(1 - sqr(dis)/(2 * sqr(radius)), -1, 1);
var _angle = darccos(_val);
space_error += sqr(_angle - expected_angle);
j = i;
}
space_error /= n_points;
space_error = sqrt(space_error);
// normalize error
var error = F(dis_error, space_error);
var error_normalized = clamp(error/max_error, 0, 1);
// get score
return (1 - error_normalized);
}