|
| 1 | +"""Feature extraction module for drawing error-based metrics in spiral drawing data.""" |
| 2 | + |
| 3 | +import numpy as np |
| 4 | +from shapely import geometry, ops |
| 5 | + |
| 6 | +from graphomotor.core import models |
| 7 | + |
| 8 | + |
| 9 | +def calculate_area_under_curve( |
| 10 | + drawn_spiral: models.Spiral, reference_spiral: np.ndarray |
| 11 | +) -> dict[str, float]: |
| 12 | + """Calculate the area between drawn and reference spirals. |
| 13 | +
|
| 14 | + This function measures the deviation between drawn and reference spirals by |
| 15 | + computing the enclosed area between them using the shapely library. Lower values |
| 16 | + indicate better adherence to the template. The algorithm works by creating polygons |
| 17 | + that connect spiral endpoints, finding intersections between lines, and calculating |
| 18 | + the total area of the resulting polygons. |
| 19 | +
|
| 20 | + Args: |
| 21 | + drawn_spiral: The spiral drawn by the subject. |
| 22 | + reference_spiral: The reference spiral. |
| 23 | +
|
| 24 | + Returns: |
| 25 | + Dictionary containing the area under curve metric |
| 26 | + """ |
| 27 | + spiral = drawn_spiral.data[["x", "y"]].values |
| 28 | + line_drawn = geometry.LineString(spiral) |
| 29 | + line_reference = geometry.LineString(reference_spiral) |
| 30 | + first_segment = geometry.LineString([spiral[0], reference_spiral[0]]) |
| 31 | + last_segment = geometry.LineString([spiral[-1], reference_spiral[-1]]) |
| 32 | + merged_line = ops.unary_union( |
| 33 | + [line_drawn, line_reference, first_segment, last_segment] |
| 34 | + ) |
| 35 | + polygons = list(ops.polygonize(merged_line)) |
| 36 | + return {"area_under_curve": sum(p.area for p in polygons)} |
0 commit comments