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
842 stars 35 forks source link

Custom element (with set-transform)'s Anchor position error #701

Open johannes-wolf opened 6 days ago

johannes-wolf commented 6 days ago

Discussed in https://github.com/cetz-package/cetz/discussions/699

Originally posted by **KiyanYang** September 24, 2024 I created a custom element, invoke `set-transform` in the element,and set `Anchor`. Externally, call this element's Anchor position error. Is there something wrong with the code? In the picture below, red line should link point A to point D1, but D1 position wrong. ![image](https://github.com/user-attachments/assets/e0dbd61c-4346-4d59-bc95-b6a0da86f15c) ```typst #import "@preview/cetz:0.2.2" #set page(width: auto, height: auto) #let prism(name: none, show-content: false, ..style) = { import cetz.draw: * group(name: name, ctx => { let default_style = ( edge-length: (2cm, 3cm, 2cm), thickness: 1pt, transform: ( (-calc.sqrt(2)/4, 1, 0, 0), ( calc.sqrt(2)/4, 0,-1, 0), ( 0, 0, 1, 0), ( 0, 0, 0, 1))) let style = cetz.styles.resolve(ctx.style, merge: style.named(), base: default_style, root: "prism") set-transform(style.transform) let a = style.edge-length.at(0); let b = style.edge-length.at(1); let c = style.edge-length.at(2); anchor("A", (a,0,0)) anchor("B", (a,b,0)) anchor("C", (0,b,0)) anchor("D", (0,0,0)) anchor("A1", (a,0,c)) anchor("B1", (a,b,c)) anchor("C1", (0,b,c)) anchor("D1", (0,0,c)) set-style(stroke: (thickness: style.thickness, cap: "round")) line("A", "B") line("B", "C") line("C", "D", stroke: (dash: "dashed")) line("D", "A", stroke: (dash: "dashed")) line("A", "A1") line("B", "B1") line("C", "C1") line("D", "D1", stroke: (dash: "dashed")) line("A1", "B1") line("B1", "C1") line("C1", "D1") line("D1", "A1") if show-content { content("A", $A$, padding: (left: -4mm, bottom: 0mm)) content("B", $B$, padding: (left: 4mm, bottom: -1mm)) content("C", $C$, padding: (left: 4mm, bottom: 0mm)) content("D", $D$, padding: (left: -4mm, bottom: 1mm)) content("A1", $A_1$, padding: (left: -5mm, bottom: 0mm)) content("B1", $B_1$, padding: (left: -4mm, bottom: 6mm)) content("C1", $C_1$, padding: (left: 0mm, bottom: 6mm)) content("D1", $D_1$, padding: (left: 0mm, bottom: 6mm)) } }) } #cetz.canvas({ prism(name: "test", show-content: true) cetz.draw.line("test.A", "test.D1", stroke: red) // Wrong location }) ```
johannes-wolf commented 6 days ago

@KiyanYang The problem seems to be the z component. It works if you remove it from your transformation matrix:

transform: (                                         
        (-calc.sqrt(2)/4, 1, 0, 0),                        
        ( calc.sqrt(2)/4, 0,-1, 0),                        
        (              0, 0, 0, 0), // Set z to 0                        
        (              0, 0, 0, 1))

Because the default transformation matrix sets z * (1/2, 1/2, 0), you have to either change the root transformation or remove the z component from the resulting vectors of your transformation.

It is not good that anchors behave like this, though. I will have a look at it.