33from compas .geometry import Frame
44from compas .scene import GeometryObject
55from matplotlib .patches import ArrowStyle
6+ from matplotlib .patches import Circle as CirclePatch
67from matplotlib .patches import FancyArrowPatch
8+ from matplotlib .transforms import ScaledTranslation
79
810from .plotterobject import PlotterSceneObject
911
@@ -12,7 +14,8 @@ class FrameObject(PlotterSceneObject, GeometryObject):
1214 """Plotter scene object for :class:`compas.geometry.Frame`.
1315
1416 The frame is drawn as its projection onto the XY plane: a red arrow for the
15- X axis and a green arrow for the Y axis, both starting at the frame origin.
17+ X axis and a green arrow for the Y axis, both starting at the frame origin,
18+ with a disc marking the origin in between the two arrows.
1619
1720 Parameters
1821 ----------
@@ -22,19 +25,27 @@ class FrameObject(PlotterSceneObject, GeometryObject):
2225 Color of the X-axis arrow.
2326 ycolor
2427 Color of the Y-axis arrow.
28+ pointsize
29+ Size of the origin marker, in points.
30+ pointcolor
31+ Color of the origin marker.
2532 """
2633
2734 def __init__ (
2835 self ,
2936 size : float = 1.0 ,
3037 xcolor : tuple [float , float , float ] = (1.0 , 0.0 , 0.0 ),
3138 ycolor : tuple [float , float , float ] = (0.0 , 1.0 , 0.0 ),
39+ pointsize : float = 5 ,
40+ pointcolor : tuple [float , float , float ] = (0.0 , 0.0 , 0.0 ),
3241 ** kwargs ,
3342 ) -> None :
3443 super ().__init__ (zorder = 3000 , ** kwargs )
3544 self .size = size
3645 self .xcolor = xcolor
3746 self .ycolor = ycolor
47+ self .pointsize = pointsize
48+ self .pointcolor = pointcolor
3849
3950 @property
4051 def frame (self ) -> Frame :
@@ -58,12 +69,27 @@ def _arrow(self, end, color) -> FancyArrowPatch:
5869 mutation_scale = 100 ,
5970 )
6071
72+ def _origin_marker (self ) -> CirclePatch :
73+ # Fixed on-screen size (in points), independent of zoom level.
74+ fig_scale = self .plotter .figure .dpi_scale_trans
75+ origin = self .frame .point
76+ translation = ScaledTranslation (origin [0 ], origin [1 ], self .axes .transData )
77+ return CirclePatch (
78+ (0 , 0 ),
79+ radius = self .pointsize / self .plotter .dpi ,
80+ facecolor = "white" ,
81+ edgecolor = self .pointcolor ,
82+ transform = fig_scale + translation ,
83+ zorder = self .zorder ,
84+ )
85+
6186 def draw (self ) -> list :
6287 origin = self .frame .point
6388 ex = origin + self .frame .xaxis .scaled (self .size )
6489 ey = origin + self .frame .yaxis .scaled (self .size )
6590 self ._mpl_objects = [
6691 self .axes .add_patch (self ._arrow (ex , self .xcolor )),
6792 self .axes .add_patch (self ._arrow (ey , self .ycolor )),
93+ self .axes .add_artist (self ._origin_marker ()),
6894 ]
6995 return self ._mpl_objects
0 commit comments