Source code for ladybug_display.extension.compass

"""Method to draw a Compass as a VisualizationSet."""
import math

from ladybug_geometry.geometry3d import Vector3D, Point3D, Plane, LineSegment3D, Arc3D

from ..geometry3d import DisplayText3D, DisplayArc3D, DisplayLineSegment3D
from ..visualization import VisualizationSet, ContextGeometry


[docs]def compass_to_vis_set(compass, z=0, custom_angles=None, projection=None, font='Arial', maj_txt_size=None, min_txt_size=None): """Translate a Ladybug Compass object into Display geometry. Args: compass: A Ladybug Compass object to be converted to display geometry. z: A number for the Z-coordinate to be used in translation. (Default: 0) custom_angles: An array of numbers between 0 and 360 to be used to generate custom angle labels around the compass. projection: Text for the name of the projection to use from the sky dome hemisphere to the 2D plane. If None, no altitude circles o labels will be drawn (Default: None). Choose from the following: * Orthographic * Stereographic font: Optional text for the font to be used in creating the text. (Default: 'Arial') maj_txt_size: An optional number for the size of the major text. If None, it will be set to one 20th of the radius. min_txt_size: An optional number for the size of the major text. Set to zero to have no minor text in the compass. If None, it will be set to half of the major text size. Returns: A VisualizationSet with the Compass represented as a single ContextGeometry. This context geometry includes these objects in the following order. - all_boundary_circles -- Three Circle objects for the compass boundary. - major_azimuth_ticks -- Line objects for the major azimuth labels. - major_azimuth_text -- Text objects for the major azimuth labels. - minor_azimuth_ticks -- Line objects for the minor azimuth labels (if applicable). - minor_azimuth_text -- Text objects for the minor azimuth labels (if applicable). - altitude_circles -- Circle objects for altitude labels (if projection is not None). - altitude_text -- Text objects for altitude labels (if projection is not None). """ # set default variables based on the compass properties maj_txt = compass.radius / 20 if maj_txt_size is None else maj_txt_size min_txt = maj_txt / 2 if min_txt_size is None else min_txt_size xaxis = Vector3D(1, 0, 0).rotate_xy(math.radians(compass.north_angle)) result = [] # list to hold all of the returned objects for i, circle in enumerate(compass.all_boundary_circles): lw = 2 if i == 0 else 1 result.append(DisplayArc3D(Arc3D.from_arc2d(circle, z), line_width=lw)) # create a method that translates LineSegment2D into DisplayLineSegment3D def from_linesegment2d(line, z, line_width=1): pt_array = ((line.p1.x, line.p1.y, z), (line.p2.x, line.p2.y, z)) ls_3d = LineSegment3D.from_array(pt_array) return DisplayLineSegment3D(ls_3d, line_width=line_width) # generate the labels and tick marks for the azimuths if custom_angles is None: for line in compass.major_azimuth_ticks: result.append(from_linesegment2d(line, z, 2)) for txt, pt in zip(compass.MAJOR_TEXT, compass.major_azimuth_points): txt_pln = Plane(o=Point3D(pt.x, pt.y, z), x=xaxis) result.append( DisplayText3D(txt, txt_pln, maj_txt, None, font, 'Center', 'Middle')) if min_txt > 0: for line in compass.minor_azimuth_ticks: result.append(from_linesegment2d(line, z)) for txt, pt in zip(compass.MINOR_TEXT, compass.minor_azimuth_points): txt_pln = Plane(o=Point3D(pt.x, pt.y, z), x=xaxis) result.append( DisplayText3D(txt, txt_pln, min_txt, None, font, 'Center', 'Middle')) else: for line in compass.ticks_from_angles(custom_angles): result.append(from_linesegment2d(line, z)) for txt, pt in zip( custom_angles, compass.label_points_from_angles(custom_angles)): t_pln = Plane(o=Point3D(pt.x, pt.y, z), x=xaxis) d_t = DisplayText3D(str(txt), t_pln, maj_txt, None, font, 'Center', 'Middle') result.append(d_t) # generate the labels and tick marks for the altitudes if projection is not None: if projection.title() == 'Orthographic': for circle in compass.orthographic_altitude_circles: arc_geo = Arc3D.from_arc2d(circle, z) result.append(DisplayArc3D(arc_geo, line_width=1, line_type='Dotted')) for txt, pt in zip(compass.ALTITUDES, compass.orthographic_altitude_points): txt_pln = Plane(o=Point3D(pt.x, pt.y, z + 0.01), x=xaxis) d_txt = DisplayText3D( str(txt), txt_pln, min_txt, None, font, 'Center', 'Top') result.append(d_txt) elif projection.title() == 'Stereographic': for circle in compass.stereographic_altitude_circles: arc_geo = Arc3D.from_arc2d(circle, z) result.append(DisplayArc3D(arc_geo, line_width=1, line_type='Dotted')) for txt, pt in zip(compass.ALTITUDES, compass.stereographic_altitude_points): txt_pln = Plane(o=Point3D(pt.x, pt.y, z + 0.01), x=xaxis) d_txt = DisplayText3D( str(txt), txt_pln, min_txt, None, font, 'Center', 'Top') result.append(d_txt) # assemble everything into a ContextGeometry and VisualizationSet con_geo = ContextGeometry('Compass', result) return VisualizationSet('Compass', [con_geo])