Newer
Older
Demo-Maker / calc_circle.py
import csv
import math
import random


class Point:
    def __init__(self, x, y):
        self.x = float(x)
        self.y = float(y)


def read_csv_file(filename):
    data = []
    with open(filename, "r") as file:
        csv_reader = csv.DictReader(file)
        for row in csv_reader:
            data.append(row)
    return data


def dist(a, b):
    return math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)


def circle_center(bx, by, cx, cy):
    B = bx * bx + by * by
    C = cx * cx + cy * cy
    D = bx * cy - by * cx
    return Point((cy * B - by * C) / (2 * D), (bx * C - cx * B) / (2 * D))


def is_inside(c, r, p):
    return dist(c, p) <= r


def get_circle_center(p1, p2, p3=None):
    if p3 is None:
        return Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2), dist(p1, p2) / 2

    center = circle_center(p2.x - p1.x, p2.y - p1.y, p3.x - p1.x, p3.y - p1.y)
    center.x += p1.x
    center.y += p1.y
    return center, dist(center, p1)


def min_circle(points):
    if len(points) == 0:
        return Point(0, 0), 0
    elif len(points) == 1:
        return points[0], 0

    shuffle = random.sample(points, len(points))
    c, r = get_circle_center(shuffle[0], shuffle[1])

    for i in range(2, len(shuffle)):
        if not is_inside(c, r, shuffle[i]):
            c, r = get_circle_center(shuffle[0], shuffle[i])
            for j in range(1, i):
                if not is_inside(c, r, shuffle[j]):
                    c, r = get_circle_center(shuffle[j], shuffle[i])
                    for k in range(j):
                        if not is_inside(c, r, shuffle[k]):
                            c, r = get_circle_center(shuffle[j], shuffle[i], shuffle[k])

    return c, r


def process_data(data, model_name):
    points = [
        Point(row[f"{model_name}_stethoscope_x"], row[f"{model_name}_stethoscope_y"])
        for row in data
    ]
    center, radius = min_circle(points)
    return radius * 2  # diameter


# Main execution
result_data = read_csv_file("output/results/results.csv")
result_convert_data = read_csv_file("output/results/results-convert.csv")

models = ["conv", "Xgboost", "lightGBM"]

print("Minimum enclosing circle diameters for each model:")
for model in models:
    result_diameter = process_data(result_data, model)
    result_convert_diameter = process_data(result_convert_data, model)
    print(f"{model}:")
    print(f"  results.csv: {result_diameter:.2f}")
    print(f"  results-convert.csv: {result_convert_diameter:.2f}")
    print()