Skip to content

Commit

Permalink
arrows, lots of arrows
Browse files Browse the repository at this point in the history
  • Loading branch information
davidaustinm committed Sep 10, 2024
1 parent 0815988 commit b7aa80d
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 23 deletions.
42 changes: 33 additions & 9 deletions prefig/core/arrow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import numpy as np
from . import utilities as util
from . import CTM
from . import user_namespace as un

# Form arrows to be used with a variety of graphical components
# Arrowheads are created as markers and then added to paths
Expand Down Expand Up @@ -143,7 +144,18 @@ def add_tactile_arrowhead_marker(diagram, path, mid=False):
# This will follow the same logic as the tactile arrow head created
# above, only the shape of a regular arrow head is slightly different
# than a tactile arrow head.
def add_arrowhead_marker(diagram, path, mid=False):
def add_arrowhead_marker(diagram,
path,
mid=False,
arrow_width=None,
arrow_angles=None):
if arrow_width is not None:
arrow_width = un.valid_eval(arrow_width)
if arrow_angles is not None:
arrow_angles = un.valid_eval(arrow_angles)
else:
arrow_angles = (24, 60)

if diagram.output_format() == 'tactile':
return add_tactile_arrowhead_marker(diagram, path)

Expand All @@ -153,21 +165,25 @@ def add_arrowhead_marker(diagram, path, mid=False):

# Dimensions are a bit different if the arrow head is at an
# end or in the middle of a path
id_data = f"_{arrow_width}_{arrow_angles[0]}_{arrow_angles[1]}"
if not mid:
id = 'arrow-head-end-'+stroke_width_str
dims = (1, 4)
id = 'arrow-head-end-'+stroke_width_str+id_data
if arrow_width is None:
arrow_width = 4
dims = (1, arrow_width)
else:
id = 'arrow-head-mid-'+stroke_width_str
dims = (1, 13/3) #11/3)
id = 'arrow-head-mid-'+stroke_width_str+id_data
if arrow_width is None:
arrow_width = 13/3
dims = (1, arrow_width) #11/3)

# If we've already created this one, we'll just move on
if diagram.has_reusable(id):
return id

# Next we'll construct the path defining the arrow head
t, s = [d/2 for d in dims]
A = math.radians(24)
B = math.radians(60)
A, B = [math.radians(angle) for angle in arrow_angles]
l = t/math.tan(A) + 0.1
x2 = l - s/math.tan(A)
x1 = x2 + (s-t)/math.tan(B)
Expand Down Expand Up @@ -267,7 +283,15 @@ def add_arrowhead_marker(diagram, path, mid=False):

return id

def add_arrowhead_to_path(diagram, location, path):
id = add_arrowhead_marker(diagram, path, location[-3:] == 'mid')
def add_arrowhead_to_path(diagram,
location,
path,
arrow_width=None,
arrow_angles=None):
id = add_arrowhead_marker(diagram,
path,
location[-3:] == 'mid',
arrow_width,
arrow_angles)
path.set(location, r'url(#{})'.format(id))

33 changes: 29 additions & 4 deletions prefig/core/circle.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,23 @@ def arc(element, diagram, parent, outline_status):
backward = 'marker-start'
if element.get('reverse', 'no') == 'yes':
forward, backward = backward, forward

if arrows > 0:
arrow.add_arrowhead_to_path(diagram, forward, arc)
arrow.add_arrowhead_to_path(
diagram,
forward,
arc,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)
if arrows > 1:
arrow.add_arrowhead_to_path(diagram, backward, arc)
arrow.add_arrowhead_to_path(
diagram,
backward,
arc,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)

if outline_status == 'add_outline':
diagram.add_outline(element, arc, parent, outline_width=2)
Expand Down Expand Up @@ -296,9 +309,21 @@ def angle(element, diagram, parent, outline_status):

if element.get('arrow', None) is not None:
if element.get('reverse', 'no') == 'yes':
arrow.add_arrowhead_to_path(diagram, 'marker-end', arc)
arrow.add_arrowhead_to_path(
diagram,
'marker-end',
arc,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)
else:
arrow.add_arrowhead_to_path(diagram, 'marker-start', arc)
arrow.add_arrowhead_to_path(
diagram,
'marker-start',
arc,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)
if outline_status == 'add_outline':
diagram.add_outline(element, arc, parent, outline_width=2)
return
Expand Down
3 changes: 2 additions & 1 deletion prefig/core/coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ def coordinates(element, diagram, root, outline_status):
ctm.scale( (destination[2]-destination[0])/float(bbox[2]-bbox[0]),
(destination[3]-destination[1])/float(bbox[3]-bbox[1]) )
ctm.translate(-bbox[0], -bbox[1])
un.valid_eval(destination_str, 'bbox')
bbox_str = '['+','.join([str(b) for b in bbox])+']'
un.valid_eval(bbox_str, 'bbox')

diagram.push_ctm([ctm, bbox])
diagram.parse(element, root, outline_status)
Expand Down
42 changes: 40 additions & 2 deletions prefig/core/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,47 @@ def line(element, diagram, parent, outline_status):
if element.get('reverse', 'no') == 'yes':
forward, backward = backward, forward
if arrows > 0:
arrow.add_arrowhead_to_path(diagram, forward, line)
arrow.add_arrowhead_to_path(
diagram,
forward,
line,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)
if arrows > 1:
arrow.add_arrowhead_to_path(diagram, backward, line)
arrow.add_arrowhead_to_path(
diagram,
backward,
line,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)

if element.get('additional-arrows', None) is not None:
additional = un.valid_eval(element.get('additional-arrows'))
if not isinstance(additional, np.ndarray):
additional = np.array([additional])
list_additional = list(additional)
list_additional.sort()

line.tag = "path"
cmds = ['M', line.get('x1'), line.get('y1')]
p1 = np.array([float(line.get('x1')), float(line.get('y1'))])
p2 = np.array([float(line.get('x2')), float(line.get('y2'))])
for additional in list_additional:
p = (1-additional)*p1 + additional*p2
cmds += ['L', util.pt2str(p)]
cmds += ['L', line.get('x2'), line.get('y2')]
line.set('d', ' '.join(cmds))
arrow.add_arrowhead_to_path(
diagram,
'marker-mid',
line,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)


util.cliptobbox(line, element, diagram)

if outline_status == 'add_outline':
Expand Down
17 changes: 14 additions & 3 deletions prefig/core/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,21 @@ def path(element, diagram, parent, outline_status):
if element.get('reverse', 'no') == 'yes':
forward, backward = backward, forward
if arrows > 0:
arrow.add_arrowhead_to_path(diagram, forward, path)
arrow.add_arrowhead_to_path(
diagram,
forward,
path,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)
if arrows > 1:
arrow.add_arrowhead_to_path(diagram, backward, path)

arrow.add_arrowhead_to_path(
diagram,
backward,
path,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)

if outline_status == 'add_outline':
diagram.add_outline(element, path, parent)
Expand Down
17 changes: 14 additions & 3 deletions prefig/core/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,21 @@ def polygon(element, diagram, parent, outline_status):
if element.get('reverse', 'no') == 'yes':
forward, backward = backward, forward
if arrows > 0:
arrow.add_arrowhead_to_path(diagram, forward, path)
arrow.add_arrowhead_to_path(
diagram,
forward,
path,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)
if arrows > 1:
arrow.add_arrowhead_to_path(diagram, backward, path)

arrow.add_arrowhead_to_path(
diagram,
backward,
path,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)

if outline_status == 'add_outline':
diagram.add_outline(element, path, parent)
Expand Down
5 changes: 5 additions & 0 deletions prefig/core/slope_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ def slope_field(element, diagram, parent, outline_status):
if element.get('arrows', 'no') == 'yes':
line_template.set('arrows', '1')

if element.get('arrow-width', None) is not None:
line_template.set('arrow-width', element.get('arrow-width'))
if element.get('arrow-angles', None) is not None:
line_template.set('arrow-angles', element.get('arrow-angles'))

# Now we'll construct each of the lines in the slope field
system = element.get('system', None) == 'yes'
spacings = element.get('spacings', None)
Expand Down
8 changes: 7 additions & 1 deletion prefig/core/vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ def vector(element, diagram, parent, outline_status):
location = 'marker-mid'
else:
location = 'marker-end'
arrow.add_arrowhead_to_path(diagram, location, vector)
arrow.add_arrowhead_to_path(
diagram,
location,
vector,
arrow_width=element.get('arrow-width', None),
arrow_angles=element.get('arrow-angles', None)
)
vector.set('type', 'vector')

if outline_status == 'add_outline':
Expand Down

0 comments on commit b7aa80d

Please sign in to comment.