Jollywatt / typst-fletcher

Typst package for drawing diagrams with arrows, built on top of CeTZ.
MIT License
409 stars 8 forks source link

Customizing path decorations for arrows #42

Open hooyuser opened 5 months ago

hooyuser commented 5 months ago

Hi, I am currently exploring how to better customize path decorations for edges in Fletcher.

In fletcher, it's easy to add wave decorations, but finer customization seems a bit harder. Here's a comparison of the current default and what I'm aiming for.

wave_arrow

Right now, my code involves a hack with hardcoded lengths that doesn't work well in all cases. Here's a snippet of what I have:

#import "@preview/fletcher:0.5.0" as fletcher: diagram, node, edge
#import "@preview/cetz:0.2.2"

Default wave arrow:  #diagram(
  $X && Y$,
  edge(
    (0,0),(2,0), $f$, "->", decorations:cetz.decorations.wave.with(
      amplitude: .06, 
      segment-length: .25
    )
  )
)

Desired wave arrow: #diagram(
  $X && Y$,
  edge(
    (0,0),(1.69,0),  "-", decorations:cetz.decorations.wave.with(  // hardcoded length 1.69
      amplitude: .06, 
      segment-length: .25
    )
  ),
  edge(
    (1.69,0),(2,0), "->", 
  ),
  edge(
    (0,0),(2,0), $f$, stroke: none
  )
)

Basic Customization

As a starting point, I'd like to adjust the length of the segment from the end of the wave to the end of the entire arrow. The default is a bit too long for what I need. To be precise, I'd like to adjust the length of the red segment in the following diagram.

Futher Customization

Ideally, I also want to recreate the following tikzcd plot.

Here's the snippet of the LaTeX code ``` \documentclass{article} \usepackage{tikz} \usetikzlibrary{cd, decorations.pathmorphing,} \tikzcdset{arrow style=tikz, squigarrow/.style={ decoration={ snake, amplitude=.25mm, segment length=2mm }, rounded corners=.1pt, decorate } } \begin{document} \[ \begin{tikzcd} X \arrow[r, "f", "(5.5T)"', squigarrow] &[1em] Y \arrow[r, "f", "(5T)"', squigarrow] &[0.6em] Z \end{tikzcd} \] \end{document} ```

I am not sure how exactly wave decoration works in Fletcher. Please correct me if I get it wrong. I guess if the total width of a wave path is fixed, the wave decoration attempts to adjust the wave length or period of the wave to match the segment-length parameter as closely as possible. So we always get sine waves spanning $n$ full periods, where $n$ is an integer.

I am aiming to adjust this so that half a wave length can match segment-length * 0.5 as closely as possible, allowing for sine waves spanning $n/2$ period. As illustrated in the above tikzcd plot, the spanning periods of two waves are 5.5 and 5 respectively.

Could you guide me on how to customize the wave decorations in Fletcher to achieve this effect? Thanks for any guidance!

johannes-wolf commented 1 week ago

CeTZ PR: https://github.com/cetz-package/cetz/pull/756