Skip to content

Commit b3e06e9

Browse files
authored
Merge pull request #1860 from wkentaro/fix/point-shape-click-selection
fix: point shapes are now selectable and deletable by clicking
2 parents 4e60ae5 + 23371dd commit b3e06e9

2 files changed

Lines changed: 49 additions & 0 deletions

File tree

labelme/shape.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ def nearestEdge(self, point, epsilon):
325325
def containsPoint(self, point) -> bool:
326326
if self.shape_type in ["line", "linestrip", "points"]:
327327
return False
328+
if self.shape_type == "point":
329+
if not self.points:
330+
return False
331+
return labelme.utils.distance(point - self.points[0]) <= self.point_size / 2
328332
if self.mask is not None:
329333
raw_y = int(round(point.y() - self.points[0].y()))
330334
raw_x = int(round(point.x() - self.points[0].x()))
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from __future__ import annotations
2+
3+
from PyQt5 import QtCore
4+
5+
from labelme.shape import Shape
6+
7+
8+
def _make_point_shape(x: float, y: float) -> Shape:
9+
"""Create a point shape with a single point at (x, y)."""
10+
shape = Shape(shape_type="point")
11+
shape.addPoint(QtCore.QPointF(x, y))
12+
return shape
13+
14+
15+
def test_point_shape_contains_center():
16+
"""Clicking exactly on a point shape should return True."""
17+
shape = _make_point_shape(100.0, 200.0)
18+
assert shape.containsPoint(QtCore.QPointF(100.0, 200.0)) is True
19+
20+
21+
def test_point_shape_contains_within_radius():
22+
"""Clicking within point_size/2 of the center should return True."""
23+
shape = _make_point_shape(100.0, 200.0)
24+
# point_size defaults to 8, so radius = 4. A point 3px away should hit.
25+
assert shape.containsPoint(QtCore.QPointF(103.0, 200.0)) is True
26+
27+
28+
def test_point_shape_at_exact_boundary():
29+
"""Clicking exactly at point_size/2 distance should return True (inclusive)."""
30+
shape = _make_point_shape(100.0, 200.0)
31+
# point_size defaults to 8, so radius = 4. Exactly 4px away should hit.
32+
assert shape.containsPoint(QtCore.QPointF(104.0, 200.0)) is True
33+
34+
35+
def test_point_shape_outside_radius():
36+
"""Clicking more than point_size/2 away should return False."""
37+
shape = _make_point_shape(100.0, 200.0)
38+
# 10px away, well outside the radius of 4
39+
assert shape.containsPoint(QtCore.QPointF(110.0, 200.0)) is False
40+
41+
42+
def test_point_shape_empty_points():
43+
"""A point shape with no points should return False, not raise."""
44+
shape = Shape(shape_type="point")
45+
assert shape.containsPoint(QtCore.QPointF(0.0, 0.0)) is False

0 commit comments

Comments
 (0)