Be less dumb calculating angles

This commit is contained in:
XANTRONIX Development 2024-01-02 16:37:43 -05:00
parent ff77b8cb96
commit 136fe6de63
3 changed files with 44 additions and 78 deletions

View file

@ -34,9 +34,16 @@ class Dial(Gauge):
return gradient
def angle(self, value: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
return self.min_angle + \
(self.max_angle - self.min_angle) * (adj / adj_max) \
- self.ANGLE_OFFSET
def draw_number(self, cr: cairo.Context, radius: float, value: float, text: str):
scale = value / self.max_value
angle = self.min_angle + ((self.max_angle - self.min_angle) * scale) - self.ANGLE_OFFSET
angle = self.angle(value)
cr.move_to(self.x + radius * self.radius * math.cos(angle) - 20,
self.y + radius * self.radius * math.sin(angle))
@ -45,11 +52,7 @@ class Dial(Gauge):
cr.stroke()
def draw_mark(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (adj / adj_max)) - self.ANGLE_OFFSET
angle = self.angle(value)
cr.move_to(self.x + (min_radius * self.radius) * math.cos(angle),
self.y + (min_radius * self.radius) * math.sin(angle))
@ -60,12 +63,7 @@ class Dial(Gauge):
cr.stroke()
def draw_needle(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (adj / adj_max)) \
- self.ANGLE_OFFSET
angle = self.angle(value)
cr.set_source_rgba(1, 0.4, 1, 0.75)
cr.set_line_width(8)
@ -106,26 +104,33 @@ class Dial(Gauge):
self.draw_needle(cr, 0.5, 0.89, self.value)
class BottomDial(Dial):
def draw_mark(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
MIN_ANGLE = 144.0 * (math.pi / 180.0)
MAX_ANGLE = 216.0 * (math.pi / 180.0)
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (adj / adj_max)) - self.ANGLE_OFFSET
def angle(self, value: float):
return super().angle((self.max_value - value) + self.min_value)
cr.move_to(self.x + (min_radius * self.radius) * math.cos(angle),
self.y + (min_radius * self.radius) * math.sin(angle))
def draw_value(self, cr: cairo.Context, radius: float, value: float, text: str, x_offset: float=0.0, y_offset: float=0.0):
angle = self.angle(value)
cr.line_to(self.x + (max_radius * self.radius) * math.cos(angle),
self.y + (max_radius * self.radius) * math.sin(angle))
cr.move_to(self.x + radius * self.radius * math.cos(angle) + x_offset,
self.y + radius * self.radius * math.sin(angle) + y_offset)
cr.show_text(text)
cr.stroke()
def draw_bg(self, cr: cairo.Context):
cr.set_line_width(24)
cr.set_source_rgb(0.2, 0.2, 0.2)
cr.arc(self.x,
self.y,
self.radius - 36,
self.MIN_ANGLE - self.ANGLE_OFFSET,
self.MAX_ANGLE - self.ANGLE_OFFSET + 4 * (math.pi / 180.0))
cr.stroke()
def draw_fg(self, cr: cairo.Context):
min_radius = 0.8
max_radius = 0.9
adj = self.value - self.min_value
adj_max = self.max_value - self.min_value
self.draw_needle(cr, min_radius, max_radius, adj_max - adj)
self.draw_needle(cr, min_radius, max_radius, self.value)

View file

@ -5,9 +5,6 @@ import cairo
from hexagram.dial import BottomDial
class FuelGauge(BottomDial):
MIN_ANGLE = 144.0 * (math.pi / 180.0)
MAX_ANGLE = 216.0 * (math.pi / 180.0)
MIN_VALUE = 0
MAX_VALUE = 15
@ -22,25 +19,8 @@ class FuelGauge(BottomDial):
self.value = 0
def draw_value(self, cr: cairo.Context, radius: float, value: float, text: str, x_offset: float):
scale = (self.max_value - value) / self.max_value
angle = self.min_angle + ((self.max_angle - self.min_angle) * scale) - self.ANGLE_OFFSET
cr.move_to(self.x + radius * self.radius * math.cos(angle) + x_offset,
self.y + radius * self.radius * math.sin(angle))
cr.show_text(text)
cr.stroke()
def draw_bg(self, cr: cairo.Context):
cr.set_line_width(24)
cr.set_source_rgb(0.2, 0.2, 0.2)
cr.arc(self.x,
self.y,
self.radius - 36,
self.MIN_ANGLE - self.ANGLE_OFFSET - 4 * (math.pi / 180.0),
self.MAX_ANGLE - self.ANGLE_OFFSET + 4 * (math.pi / 180.0))
cr.stroke()
super().draw_bg(cr)
cr.select_font_face(self.FONT_FACE,
cairo.FontSlant.NORMAL,
@ -67,4 +47,4 @@ class FuelGauge(BottomDial):
min_radius = 0.82
cr.set_source_rgb(1, 1, 1)
self.draw_mark(cr, min_radius, 0.87, self.max_value - level)
self.draw_mark(cr, min_radius, 0.87, level)

View file

@ -4,9 +4,6 @@ import cairo
from hexagram.dial import BottomDial
MIN_ANGLE = 144.0 * (math.pi / 180.0)
MAX_ANGLE = 216.0 * (math.pi / 180.0)
class Thermometer(BottomDial):
MIN_VALUE = 85
MAX_VALUE = 110
@ -21,31 +18,8 @@ class Thermometer(BottomDial):
self.MIN_VALUE,
self.MAX_VALUE)
def draw_needle(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
super().draw_needle(cr, min_radius, max_radius, self.max_value - value)
def draw_value(self, cr: cairo.Context, radius: float, value: float, text: str, x_offset: float, y_offset: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
scale = adj / adj_max
angle = self.min_angle + ((self.max_angle - self.min_angle) * scale) - self.ANGLE_OFFSET
cr.move_to(self.x + radius * self.radius * math.cos(angle) + x_offset,
self.y + radius * self.radius * math.sin(angle) + y_offset)
cr.show_text(text)
cr.stroke()
def draw_bg(self, cr: cairo.Context):
cr.set_line_width(24)
cr.set_source_rgb(0.2, 0.2, 0.2)
cr.arc(self.x,
self.y,
self.radius - 36,
self.MIN_ANGLE - self.ANGLE_OFFSET,
self.MAX_ANGLE - self.ANGLE_OFFSET + 4 * (math.pi / 180.0))
cr.stroke()
super().draw_bg(cr)
cr.select_font_face(self.FONT_FACE,
cairo.FontSlant.NORMAL,
@ -54,17 +28,24 @@ class Thermometer(BottomDial):
cr.set_font_size(self.radius * 0.1)
cr.set_source_rgb(1, 1, 1)
self.draw_value(cr, 0.78, self.min_value, "C", -25, 0)
#self.draw_value(cr, 0.78, self.min_value, "C", -25, 0)
self.draw_value(cr, 0.78, self.min_value, "C")
cr.set_source_rgb(1, 0, 0)
self.draw_value(cr, 0.75, self.max_value, "H", -5, 0)
#self.draw_value(cr, 0.75, self.max_value, "H", -5, 0)
self.draw_value(cr, 0.75, self.max_value, "H")
cr.set_line_width(6.0)
for level in range(self.min_value, self.max_value, math.ceil((self.max_value - self.min_value ) / 9)):
level = self.min_value
incr = (self.max_value - self.min_value) / 9
while level <= self.max_value:
if level >= self.WARN_VALUE:
cr.set_source_rgb(0.8, 0, 0)
else:
cr.set_source_rgb(1, 1, 1)
self.draw_mark(cr, 0.83, 0.87, level)
level += incr