Skip to content

Interest in supporting perspective division? #988

@TravisWhitaker

Description

@TravisWhitaker

Thank you very much for this package! And please forgive any misunderstandings I have; I'm not terribly familiar with the package internals.

I've found that for certain types of 3D diagrams, a perspective projection rather than an orthographic one sometimes conveys the idea more clearly. I've found this is particularly the case when dealing with round things, e.g.

#import "@preview/cetz:0.4.2": canvas, draw

#set page(width: auto, height: auto, margin: 0.6pt)

#let sph-to-cart(r, theta, phi) = (
  x: r * calc.sin(theta) * calc.cos(phi),
  y: r * calc.sin(theta) * calc.sin(phi),
  z: r * calc.cos(theta)
)

#set text(size: 20pt)

#canvas(length: 6cm, {
  import draw: *

  circle((0,0,0), radius:0.0125, fill: black)

  ortho(x: -60deg, y:0deg, z:-100deg, {
    
    line((0,0,0), (1,0,0), stroke: red, mark: (end: "stealth"))
    line((0,0,0), (0,1,0), stroke: green, mark: (end: "stealth"))
    line((0,0,0), (0,0,1), stroke: blue, mark: (end: "stealth"))

    content((1.1,0,0), $x$)
    content((0,1.1,0), $y$)
    content((0, 0, 1.1), $z$)

    for phi in range(0, 360, step: 45) {
      let points = ()
      for theta in range(0, 181, step: 1) {
        points.push(sph-to-cart(1, theta * calc.pi / 180, phi * calc.pi / 180))
      }
      line(..points, stroke: (paint: gray, thickness: 0.5pt))
    }

    for theta in (30, 60, 90, 120, 150) {
      let points = ()
      for phi in range(0, 361, step: 1) {
        points.push(sph-to-cart(1, theta * calc.pi / 180, phi * calc.pi / 180))
      }
      line(..points, stroke: (paint: gray, thickness: 0.5pt))
    }
  })
})

My understanding is that Cetz is already using homogeneous coordinates for everything internally, and indeed it's already possible to override the 4x4 view matrix. I think all that would be necessary to enable a true perspective projection instead of orthographic ones would be to add an option to do the final (x/w, y/w, z/w) perspective division step.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions