From 136fe6de63db57d1106e23e2316fde4b7174a526 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 2 Jan 2024 16:37:43 -0500 Subject: [PATCH] Be less dumb calculating angles --- py/hexagram/dial.py | 57 +++++++++++++++++++++++-------------------- py/hexagram/fuel.py | 24 ++---------------- py/hexagram/thermo.py | 41 +++++++++---------------------- 3 files changed, 44 insertions(+), 78 deletions(-) diff --git a/py/hexagram/dial.py b/py/hexagram/dial.py index 147cee8..c51120f 100644 --- a/py/hexagram/dial.py +++ b/py/hexagram/dial.py @@ -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) diff --git a/py/hexagram/fuel.py b/py/hexagram/fuel.py index 33dc37a..5cb4101 100644 --- a/py/hexagram/fuel.py +++ b/py/hexagram/fuel.py @@ -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) diff --git a/py/hexagram/thermo.py b/py/hexagram/thermo.py index 11e0b9f..64e17bb 100644 --- a/py/hexagram/thermo.py +++ b/py/hexagram/thermo.py @@ -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