Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync Custom Start Degree with Numbering Position #24

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions render_knob_scale.inx
Original file line number Diff line number Diff line change
@@ -5,24 +5,33 @@
<dependency type="executable" location="inx">render_knob_scale.py</dependency>
<param name="tab" type="notebook">
<page name="general_settings" gui-text="General">
<param name="x" type="float" min="-1000" max="10000" precision="3" gui-text="Center X:">0</param>
<param name="y" type="float" min="-1000" max="10000" precision="3" gui-text="Center Y:">0</param>
<param name="radius" type="float" min="0.001" max="10000" precision="3" gui-text="Knob radius:">100</param>
<param name="angle" type="float" min="90.0" max="360.0" precision="3" gui-text="Angle">300</param>
<param name="linewidth" type="float" min="0.001" max="100" precision="3" gui-text="Line width">1</param>
<param name="x" type="float" min="-1000" max="10000" precision="3" gui-text="Center X:">0</param>
<param name="y" type="float" min="-1000" max="10000" precision="3" gui-text="Center Y:">0</param>
<param name="radius" type="float" min="0.001" max="10000" precision="3" gui-text="Knob radius:">100</param>
<param name="angle" type="float" min="90.0" max="360.0" precision="3" gui-text="Angle">300</param>
<param name="linewidth" type="float" min="0.001" max="100" precision="3" gui-text="Line width">1</param>
<param name="draw_arc" type="bool" gui-text="Draw Arc">true</param>
<param name="draw_centering_circle" type="bool" gui-text="Draw Centering Circle">false</param>
<param name="units" type="optiongroup" gui-text="Units" appearance="combo">
<item value="px">px</item>
<item value="mm">mm</item>
</param>
<param name="numbering_position" type="optiongroup" gui-text="Numbering Position" appearance="combo">
<item value="top">Top</item>
<item value="left">Left</item>
<item value="right">Right</item>
<item value="bottom">Bottom</item>
</param>
<param name="custom_start_degree" type="float" min="0.0" max="360.0" precision="3" gui-text="Custom Start Degree (Overrides Position):">0</param>
<param name="draw_circles" type="bool" gui-text="Draw Circles">true</param>
<param name="skip_mark_at_gap" type="bool" gui-text="Skip mark at gap">false</param>
</page>

<page name="ticks_settings" gui-text="Marks">
<param name="n_ticks" type="int" min="2" max="100" gui-text="Number of tick marks:">2</param>
<param name="ticksize" type="float" min="0.001" max="1000" precision="3" gui-text="Tick size: ">10</param>
<param name="n_subticks" type="int" min="0" max="100" gui-text="Number of subticks:">1</param>
<param name="subticksize" type="float" min="0.001" max="1000" precision="3" gui-text="Subtick size: ">5</param>
<param name="n_ticks" type="int" min="2" max="100" gui-text="Number of tick marks:">2</param>
<param name="ticksize" type="float" min="0.001" max="1000" precision="3" gui-text="Tick size: ">10</param>
<param name="n_subticks" type="int" min="0" max="100" gui-text="Number of subticks:">1</param>
<param name="subticksize" type="float" min="0.001" max="1000" precision="3" gui-text="Subtick size: ">5</param>
<param name="style" type="optiongroup" gui-text="Scale style" appearance="combo">
<item value="marks_inwards">Marks inwards</item>
<item value="marks_outwards">Marks outwards</item>
@@ -36,8 +45,8 @@
<param name="rounding_level" type="int" min="0" max="100" gui-text="Rounding Float to">0</param>
<param name="text_size" type="float" min="0.001" max="1000" precision="3" gui-text="Labels size">10</param>
<param name="text_offset" type="float" min="-1000" max="1000" precision="3" gui-text="Offset">20</param>
<param name="start_value" type="float" min="-10000" max="10000" precision="3" gui-text="Start Value">0</param>
<param name="stop_value" type="float" min="-10000" max="10000" precision="3" gui-text="Stop Value">10</param>
<param name="start_value" type="float" min="-10000" max="10000" precision="3" gui-text="Start Value">0</param>
<param name="stop_value" type="float" min="-10000" max="10000" precision="3" gui-text="Stop Value">10</param>
</page>
</param>

183 changes: 145 additions & 38 deletions render_knob_scale.py
Original file line number Diff line number Diff line change
@@ -122,6 +122,92 @@ def __init__(self):
# Dummy
self.arg_parser.add_argument("--tab")

self.arg_parser.add_argument("--numbering_position",
type=str,
dest="numbering_position", default="bottom",
help="Starting position for numbering (top, middle, bottom)")
self.arg_parser.add_argument("--custom_start_degree",
type=float,
dest="custom_start_degree", default=0.0,
help="Custom degree start position (Overrides numbering position)")

self.arg_parser.add_argument("--draw_circles",
type=inkex.Boolean,
dest="draw_circles", default='True',
help="Whether to draw circles or not")

self.arg_parser.add_argument("--skip_mark_at_gap",
type=inkex.Boolean,
dest="skip_mark_at_gap",
default='False',
help="Skip the mark at the gap position.")

def draw_knob_arc(self, radius, parent, transform=''):
# Determine the start point angle based on custom start degree or numbering position
start_point_angle = self.get_start_angle()

# Calculate the end point angle based on the arc angle
total_angle = radians(self.options.angle)
end_point_angle = start_point_angle + total_angle

# Convert all necessary values to strings
style = {
'stroke': '#000000',
'stroke-width': str(self.options.linewidth),
'fill': 'none'
}

ell_attribs = {
'style': str(inkex.Style(style)),
inkex.addNS('cx', 'sodipodi'): str(self.x_offset), # Convert to string
inkex.addNS('cy', 'sodipodi'): str(self.y_offset), # Convert to string
inkex.addNS('rx', 'sodipodi'): str(radius), # Convert to string
inkex.addNS('ry', 'sodipodi'): str(radius), # Convert to string
inkex.addNS('start', 'sodipodi'): str(float(start_point_angle)), # Explicit float to string
inkex.addNS('end', 'sodipodi'): str(float(end_point_angle)), # Explicit float to string
inkex.addNS('open', 'sodipodi'): 'true', # Open arc to leave a gap
inkex.addNS('type', 'sodipodi'): 'arc',
'transform': str(transform) # Ensure transform is a string
}

# Create the arc element in the parent SVG element
etree.SubElement(parent, inkex.addNS('path', 'svg'), ell_attribs)


def get_start_angle(self):
# Use custom start degree if set
if self.options.custom_start_degree != 0.0:
return radians(self.options.custom_start_degree)

# Otherwise, use the numbering position
return self.get_numbering_position_angle()


def get_numbering_position_angle(self):
# Returns the appropriate start angle for the numbering position
if self.options.numbering_position == "top":
return pi / 2 # Top (90 degrees)
elif self.options.numbering_position == "left":
return pi # Left (180 degrees)
elif self.options.numbering_position == "right":
return 0 # Right (0 degrees)
elif self.options.numbering_position == "bottom":
return -pi / 2 # Bottom (270 degrees)
else:
# Default to top (90 degrees)
return pi / 2



def get_gap_angle(self):
# Calculate the gap angle based on the custom start degree or numbering position
if self.options.custom_start_degree != 0.0:
# Use custom start degree if set
return radians(self.options.custom_start_degree)
else:
# Use the numbering position if custom start degree is not set
return self.get_numbering_position_angle()

def draw_text(self, textvalue, radius, angular_position, text_size, parent):
# Create text element
text = etree.Element(inkex.addNS('text','svg'))
@@ -142,27 +228,6 @@ def draw_text(self, textvalue, radius, angular_position, text_size, parent):

text.set('style', str(inkex.Style(style)))
parent.append(text)
def draw_knob_arc(self, radius, parent, angle, transform='' ):

start_point_angle = (angle - pi)/2.0
end_point_angle = pi - start_point_angle

style = { 'stroke' : '#000000',
'stroke-width' : str(self.options.linewidth),
'fill' : 'none' }
ell_attribs = {'style': str(inkex.Style(style)),
inkex.addNS('cx','sodipodi') :str(self.x_offset),
inkex.addNS('cy','sodipodi') :str(self.y_offset),
inkex.addNS('rx','sodipodi') :str(radius),
inkex.addNS('ry','sodipodi') :str(radius),
inkex.addNS('start','sodipodi') :str(end_point_angle),
inkex.addNS('end','sodipodi') :str(start_point_angle),
inkex.addNS('open','sodipodi') :'true', #all ellipse sectors we will draw are open
inkex.addNS('type','sodipodi') :'arc',
'transform' :transform

}
ell = etree.SubElement(parent, inkex.addNS('path','svg'), ell_attribs )

def draw_centering_circle(self, radius, parent):

@@ -179,24 +244,32 @@ def draw_centering_circle(self, radius, parent):
ell = etree.SubElement(parent, inkex.addNS('path','svg'), ell_attribs )

def draw_circle_mark(self, x_offset, y_offset, radius, mark_angle, mark_length, parent):
# Check if the circle should be skipped at the gap
gap_angle = self.get_gap_angle() # This calculates the angle where the gap is

cx = x_offset + radius*cos(mark_angle)
cy = y_offset + radius*sin(mark_angle)
if self.options.skip_mark_at_gap and abs(mark_angle - gap_angle) < 0.01: # Small tolerance to check for gap
return # Skip drawing the circle if it's at the gap

# Continue with drawing the circle
cx = x_offset + radius * cos(mark_angle)
cy = y_offset + radius * sin(mark_angle)
r = mark_length / 2.0

style = {
'stroke': '#000000',
'stroke-width':'0',
'fill': '#000000'
}
'stroke': '#000000',
'stroke-width': '0',
'fill': '#000000'
}

circ_attribs = {
'style':str(inkex.Style(style)),
'cx':str(cx),
'cy':str(cy),
'r':str(r)
}
circle = etree.SubElement(parent, inkex.addNS('circle','svg'), circ_attribs )
'style': str(inkex.Style(style)),
'cx': str(cx),
'cy': str(cy),
'r': str(r)
}

circle = etree.SubElement(parent, inkex.addNS('circle', 'svg'), circ_attribs)


def draw_knob_line_mark(self, x_offset, y_offset, radius, mark_angle, mark_length, parent):
x1 = x_offset + radius*cos(mark_angle)
@@ -218,23 +291,42 @@ def draw_knob_line_mark(self, x_offset, y_offset, radius, mark_angle, mark_lengt
line = etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs )

def draw_tick(self, radius, mark_angle, mark_size, parent):
if (self.options.style == 'marks_inwards') or (self.options.style == 'marks_outwards'):
# Check if the mark should be skipped at the gap
gap_angle = self.get_gap_angle()

if self.options.skip_mark_at_gap and abs(mark_angle - gap_angle) < 0.01: # Small tolerance to check for gap
return # Skip drawing the mark if it's at the gap

# Continue with the usual drawing logic for ticks (marks)
if self.options.style == 'marks_inwards':
self.draw_knob_line_mark(self.x_offset, self.y_offset, radius + mark_size, mark_angle, -mark_size, parent)
elif self.options.style == 'marks_outwards':
self.draw_knob_line_mark(self.x_offset, self.y_offset, radius, mark_angle, mark_size, parent)
elif self.options.style == 'marks_circles':
elif self.options.style == 'marks_circles' and self.options.draw_circles:
self.draw_circle_mark(self.x_offset, self.y_offset, radius, mark_angle, mark_size, parent)

def get_tick_angles(self):
n_ticks = self.options.n_ticks
if n_ticks <= 0:
return []

angle = radians(self.options.angle)
start_angle = 1.5*pi - 0.5*angle

# Use custom degree if set, otherwise default to numbering position
if self.options.custom_start_degree != 0.0:
start_angle = radians(self.options.custom_start_degree)
else:
if self.options.numbering_position == "top":
start_angle = pi / 2 - 0.5 * angle
elif self.options.numbering_position == "middle":
start_angle = 0 - 0.5 * angle
else: # default to bottom
start_angle = 1.5 * pi - 0.5 * angle

if self.options.logarithmic_ticks:
tick_angles = []
for i in range(n_ticks):
tick_angle = start_angle + angle*log(i+1)/log(n_ticks)
tick_angle = start_angle + angle * log(i+1) / log(n_ticks)
tick_angles.append(tick_angle)
return tick_angles
else:
@@ -286,8 +378,23 @@ def get_subtick_angles(self):
subtick_angles.append(cur_tick_angle + tick_delta * fraction)
return subtick_angles

def update_custom_start_degree_based_on_numbering_position(self):
# If the numbering position is changed, set the custom start degree accordingly
if self.options.custom_start_degree == 0.0:
if self.options.numbering_position == "top":
self.options.custom_start_degree = 90 # Top corresponds to 90 degrees
elif self.options.numbering_position == "left":
self.options.custom_start_degree = 180 # Left corresponds to 180 degrees
elif self.options.numbering_position == "right":
self.options.custom_start_degree = 0 # Right corresponds to 0 degrees
elif self.options.numbering_position == "bottom":
self.options.custom_start_degree = 270 # Bottom corresponds to 270 degrees


def effect(self):

self.update_custom_start_degree_based_on_numbering_position()

parent = self.svg.get_current_layer()
radius = self.svg.unittouu(str(self.options.radius) + self.options.units)
self.x_offset = self.svg.unittouu(str(self.options.x) + self.options.units)