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

Add `radius` to corners created by cetz (zigzag) line #514

Open Andrew15-5 opened 6 months ago

Andrew15-5 commented 6 months ago
#import "@preview/cetz:0.2.1"
#cetz.canvas({
  import cetz.draw: *
  let box(coordinates, ..args) = group(..args, {
    anchor("default", coordinates)
    let w = 3
    let h = 1.7
    rect((), (rel: (w, h)), name: "a")
    copy-anchors("a")
  })
  box((0,0), name: "2")
  box((rel: (4, -3), to: "2"), name: "3")
  let start = (name: "2", anchor: -20deg)
  let end = ("3.west")
  let mid = (start, 50%, end)
  line(start, (start, "-|", mid), (mid, "|-", end), end, mark: (end: ">", fill: black))
})

image

So the corners should be cut along the circle's arc:

image

465 is related. The problem I see is that, for example, in Dia you have a zigzag line (that looks exactly like on the screenshots above; other some other drawing tools probably have the same thing as well). But cetz already have a zigzag function that is used for another things. So maybe a zigzag-line can be added, where you pass a start and end coordinates and give a direction from which it can determine how to draw a perpendicular line (it also can use other parameters for high customizability).

fenjalien commented 6 months ago

This sounds like tikz's rounded corners option (https://tikz.dev/tikz-paths#pgf.rounded:corners). This would definitely benefit from #465 and #467.

Your zigzag idea also sound's like a tikz extension package: https://anorien.csc.warwick.ac.uk/mirrors/CTAN/graphics/pgf/contrib/tikz-ext/doc/tikz-ext-manual.pdf#section.9

As a work around for the rounded corners, it shouldn't be too hard to create your own element:

line((0,0), (1,0))
arc((), start: 90deg, stop: 0deg)
line((), (rel: (0, -1)))
arc((), start: 180deg, stop: 270deg)
line((), (rel: (1, 0)))
Andrew15-5 commented 6 months ago

The problem with this workaround is that it changes where the end of the line would be depending on radius. This also means that my MWA gets much more complicated (with offsets to the already complex coordiantes):

#import "@preview/cetz:0.2.1"
#let radius = 0.2
#cetz.canvas({
  import cetz.draw: *
  set-style(line: (mark: (end: ">", fill: black)))
  let box(coordinates, ..args) = group(..args, {
    anchor("default", coordinates)
    let w = 3
    let h = 1.7
    rect((), (rel: (w, h)), name: "a")
    copy-anchors("a")
  })

  box((0, 0), name: "2")
  box((rel: (4, -3), to: "2"), name: "3")
  let start = (name: "2", anchor: -20deg)
  let end = ("3.west")
  let mid = (start, 50%, end)
  let start-mid = (start, "-|", mid) // corner
  let end-mid = (mid, "|-", end) // corner
  line(start, (rel: (-radius, 0), to: start-mid), mark: none)
  let angle = 90deg
  arc((), radius: radius, start: angle, stop: angle - 90deg)
  line(
    (rel: (0, -radius), to: start-mid),
    (rel: (0, radius), to: end-mid),
    mark: none,
  )
  let angle = 180deg
  arc((), radius: radius, start: angle, stop: angle + 90deg)
  line((rel: (radius, 0), to: end-mid), end)
})

image

Thanks for the tip. If it was urgent, then I would've used it, but for now, I don't think complexity is worth the smoothing. Unless I will be able to wrap it in a function that will be highly reusable. At which point I will create a zigzag-line myself. Which is cool, but it probably will be very difficult.

Andrew15-5 commented 6 months ago

Speaking of zigzag-line, there are some case where it doesn't just go left, down, right, but can make 4 or even more turns. I saw somewhere a thing like "r,u,l,d", which can be used in flowchart loops and other stuff. Basically, you provide a list of directions and the zigzag line automatically calculates where all the right angles should appear and draws the line. Maybe it was PlantUML, but I'm not sure. The point is, that maybe something similar should be added to cetz. The only problem is that this form of direction will only work for normally-oriented things, unless you will be able to provide vectors/degrees as a direction (not only "r" for right etc).

Update: it was fletcher.