cetz-package / cetz

CeTZ: ein Typst Zeichenpaket - A library for drawing stuff with Typst.
https://cetz-package.github.io
GNU Lesser General Public License v3.0
733 stars 34 forks source link

transformation of named coordinate in specific angles fails #580

Closed yagshi closed 1 month ago

yagshi commented 1 month ago

There are some specific angles (e.g. around 70 deg) that cause strange transformation results.

The example code is here.

#import "@preview/cetz:0.2.2"

#cetz.canvas({
    import cetz.draw: *
    for i in range(0, 360, step: 10) {
    let th = 1deg * i
    set-ctx(ctx => {
        ctx.transform = (
        (calc.cos(th), -calc.sin(th), 0, 0),
        (-calc.sin(th), -calc.cos(th), 0, 0),
        (0, 0, 0, 0),
        (0, 0, 0, 1),
        )
        return ctx
    })
    circle((0deg, 5), radius: 0.1, name: "X", fill: luma(200))
    line("X", (rel: (2,0)))
    content((), [#th])
    }
})

After compilation with Typst 0.10.0 (cf2f789c), I've got the attached result. cetzerror

johannes-wolf commented 1 month ago

Those are due to rounding errors accumulating when doing the transformations. The problem is how anchors are handled. A workaround for your example is to not use the "X" anchor for the line (you can also use set-transform to save some lines):

#cetz.canvas({
  import cetz.draw: *
  for i in range(0, 360, step: 10) {
    let th = 1deg * i
    set-transform(
      ((calc.cos(th), -calc.sin(th), 0, 0),
       (-calc.sin(th), -calc.cos(th), 0, 0),
       (0, 0, 0, 0),
       (0, 0, 0, 1),)
    )

    circle((0deg, 5), radius: 0.1, name: "X", fill: luma(200))
    line((), (rel: (2,0)))
    content((), [#th])
  }
})

We have to fix the anchor de-transform/retransform as it accumulates floating point rounding errors very fast.

johannes-wolf commented 1 month ago

Fix is ready :)

yagshi commented 1 month ago

Thank you for the workaround and fixes! I'll try it and I'm looking forward your fixes to be pulled.