Coverage for src/min_circle/utils/circle.py: 100%

17 statements  

« prev     ^ index     » next       coverage.py v7.10.4, created at 2025-08-19 00:41 +0000

1"""Circle utility class for representing and visualizing circles. 

2 

3This module provides a Circle class for representing circles in 2D space, 

4with methods for checking point containment and visualization. 

5""" 

6 

7from dataclasses import dataclass 

8 

9import numpy as np 

10import plotly.graph_objects as go 

11 

12 

13@dataclass(frozen=True) 

14class Circle: 

15 """A 2D circle representation. 

16 

17 This class represents a circle in 2D space, defined by its center coordinates 

18 and radius. It provides methods for checking if points are contained within 

19 the circle and for visualizing the circle using Plotly. 

20 

21 Attributes: 

22 center: A numpy array of shape (2,) representing the x,y coordinates of the center 

23 radius: The radius of the circle 

24 """ 

25 

26 center: np.ndarray 

27 radius: float 

28 

29 def __post_init__(self) -> None: 

30 """Validate that the center is a 2D point. 

31 

32 Raises: 

33 AssertionError: If the center is not a 2D point (shape != (2,)) 

34 """ 

35 assert self.center.shape == (2,), "Center must be a 2D point with shape (2,)" 

36 

37 def contains(self, point: np.ndarray, tolerance: float = 1e-10) -> bool: 

38 """Check if a point lies within or on the circle. 

39 

40 Args: 

41 point: A numpy array representing the point to check 

42 tolerance: A small value to account for floating-point errors 

43 

44 Returns: 

45 True if the point is inside or on the circle boundary, False otherwise 

46 """ 

47 return np.linalg.norm(point - self.center) <= self.radius + tolerance 

48 

49 def scatter(self, num: int = 100, color: str = "red") -> go.Scatter: 

50 """Create a Plotly Scatter trace representing the circle. 

51 

52 Args: 

53 num: Number of points to use for drawing the circle 

54 color: Color of the circle line 

55 

56 Returns: 

57 A Plotly Scatter object that can be added to a figure 

58 """ 

59 # Generate points along the circle 

60 t = np.linspace(0, 2 * np.pi, num=num) 

61 radius = self.radius 

62 circle_x = self.center[0] + radius * np.cos(t) 

63 circle_y = self.center[1] + radius * np.sin(t) 

64 

65 # Create and return the Scatter trace 

66 return go.Scatter( 

67 x=circle_x, 

68 y=circle_y, 

69 mode="lines", 

70 line=dict(color=color, width=2), 

71 name=f"Circle(r = {self.radius:.3f})", 

72 )