jneug / typst-finite

Typst-setting finite automata with CeTZ.
MIT License
50 stars 0 forks source link

examples? #3

Closed Kreijstal closed 8 months ago

Kreijstal commented 9 months ago

do you have a typst with lots of examples?

Kreijstal commented 9 months ago

also can you order nodes in a grid ala tikz? image

Jakob-Ziechmann commented 9 months ago

Hi I recreated the examples you provided in finite. This should be most of the features you need when working with automata:

image

#import "@preview/finite:0.3.0": automaton
#automaton((
    q0: (q1: 0, q2: 1),
    q1: (q1: (0, 1)),
    q2: (q2: 1, q3: 0),
    q3: (q2: 1),
  ), 

  layout: ( 
    // defining positions of nodes
    q0: (0,0),
    q1: (3,0),
    q2: (6,0),
    q3: (9,0),
  ), 

  style: (
    // defining final nodes
    q3: (final: true),
    q1: (final: true),

    // defining curvature of transitions
    q0-q1: (curve: 0),
    q0-q2: (curve: -1.5),
    q2-q3: (curve: .5),
    q3-q2: (curve: .5),

    // positioning loops to self
    q2-q2: (anchor: bottom)
  ),
)

According to the manual Finite provides predefined layout behaviour to swiftly generate automaton. But I couldn't figure out how to use these layouts. Luckily it is easy to implement a basic version by yourself. image

#import "@preview/finite:0.3.0": automaton
#let aut = (
  q0: (q1: "b", q3: "a"),
  q1: (q1: "b", q2: "a"),
  q2: (q1: "b"),
  q3: (q3: "a,b"),
)

#let layout = (:) 
#{
  let columns = 3 
  let scaling = 3

  let (posX, posY) = (0,0)
  for state in aut.keys() {
    if(state not in layout) {
      layout.insert(state, (posX * scaling, posY * scaling))

      posX += 1 
      if(posX >= columns) {
        posX = 0 
        posY -= 1
      }
    }
  }
}

#let style = (
  q0-q1: (curve: 0),
  q0-q3: (curve: 0),

  q3-q3: (anchor: bottom)
)

#automaton(
  aut,
  layout: layout,
  style: style,
)
jneug commented 8 months ago

Hi there. Positioning states is pretty straightforward, as @Jakob-Ziechmann showed. Just provide a dict with the states as names and the CeTZ coordinates as values.

Finite ships with some more dynamic layouts, that work with different state styles and still try to position states with different sizes in a specific way. In your case, you could use the grid layout like this:

#import "@preview/finite:0.3.0": automaton, layout

#let aut = (
  q0: (q1: "b", q3: "a"),
  q1: (q1: "b", q2: "a"),
  q2: (q1: "b"),
  q3: (q3: "a,b"),
)

#let style = (
  q0-q1: (curve: 0),
  q0-q3: (curve: 0),

  q3-q3: (anchor: bottom)
)

#automaton(
  aut,
  layout: layout.grid.with(columns: 3, spacing: (2, -4)),
  style: style,
)

The result should look just about like your example.


I could properly maintain finite in the second half of 2023, since my work schedule didn't leave much spare time, but I hope to update finite in the near future. I will then add more examples and an updated manual.