Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] translate() in polar coordinates #599

Open
tapyu opened this issue May 21, 2024 · 7 comments
Open

[feature request] translate() in polar coordinates #599

tapyu opened this issue May 21, 2024 · 7 comments

Comments

@tapyu
Copy link
Contributor

tapyu commented May 21, 2024

Currently, draw.translate() function receives as input "a single vector or any combination of the named arguments x, y and z to translate by." (vide manual). However, this is quite restrictive once we cannot pass, for example, polar coordinates.

Consider the following MWE:

#import "@preview/cetz:0.2.2": canvas, plot, draw, coordinate, vector
#set page(width: auto, height: auto, margin: .5cm)

#let draw-me(radius, angle) = {
  draw.group({
    draw.translate(angle: angle, radius: radius)
      draw.line(
        (-0.2,+0.2),
        (rel: (+0.2,-0.2)),
        (rel: (+0.2,+0.2)),
      )
  })
}

#canvas({
  draw.circle((0,0), radius: 0.1)
  draw-me(2, 30deg)
})

This produces

image

translate() doesn't work when polar coordinates is passed.

By changing

draw.translate(angle: angle, radius: radius)

by

draw.translate((radius*calc.cos(angle), radius*calc.sin(angle)))

We can achieve the desired result

image

It would be interesting to overload translate() so that polar coordinates can also be handled by this function.

PS: I am not sure whether relative coordinates can be handled.

@johannes-wolf
Copy link
Member

You can use set-origin(<coordinate>), which allows passing any coordinate, including polar:

set-origin((angle, radius)) or set-origin((angle: angle, radius: radius))

@johannes-wolf
Copy link
Member

But I think adding said functionality to translate is a good idea.

@tapyu
Copy link
Contributor Author

tapyu commented May 21, 2024

You can use set-origin(), which allows passing any coordinate, including polar

Yeah, that might be a workaround.

But I think adding said functionality to translate is a good idea.

Agreed.

@fenjalien
Copy link
Member

Didn't we previously allow passing coordinates to translate but changed it in favour of set-origin?

@tapyu what are the cases where being able to translate with polar coordinates are useful? Examples etc.

@tapyu
Copy link
Contributor Author

tapyu commented May 22, 2024

@tapyu what are the cases where being able to translate with polar coordinates are useful? Examples etc.

Okay, I can give a very illustrative example:

#import "@preview/cetz:0.2.2": canvas, plot, draw, coordinate, decorations
#set page(width: auto, height: auto, margin: .5cm)

#let draw-satelite(height, angle, name) = {
  // draw.move-to("ground-station.tip")
  draw.group(
      name: name, {
        draw.set-origin("ground-station.tip")
        draw.translate(x: height*calc.cos(90deg-angle), y: height*calc.sin(90deg-angle))
        draw.rotate(-angle)
        draw.anchor("tip", (0,0))
          draw.line(
            (-0.2,+0.2),
            (rel: (+0.2,-0.2)),
            (rel: (+0.2,+0.2)),
          )
          draw.circle((rel: (-0.2, 0.07)), radius: (0.5,0.2), name: "antenna-base")
          draw.rect((rel: (0,0.1)), (rel: (1, 1)), name: "body", anchor: "east")
          draw.rect("body.east", (rel: (0.5, 0.5)), anchor: "north")
          draw.rect("body.west", (rel: (-0.5, 0.5)), anchor: "north")
      }
    )
}

#let draw-ground-station() = {
  draw.group(name: "ground-station", {
      draw.line(name:"base", "earth.80deg", (rel: (0,1), to:"earth.90deg"), "earth.100deg")
      
      draw.move-to("base.50%")
      draw.move-to((rel: (y: 1)))
      draw.move-to((rel: (angle: 320deg, radius: 1)))
      draw.arc((), start: 320deg, stop: 220deg, mode: "CLOSE", name: "antenna-arc")

      draw.anchor("tip", (rel: (0, 0.4), to: "antenna-arc.chord-center"))
      
      draw.line("tip", (rel:(0.2,0), to: "antenna-arc.chord-center"))
      draw.line("tip", (rel:(-0.2,0), to: "antenna-arc.chord-center"))
  })
}

#canvas({
  draw.arc((0,0), start: 45deg, stop: 135deg, radius: 5, name: "earth")

  // the layer
  draw.move-to("earth.chord-center")
  draw.move-to((rel: (angle: 70.1, radius: 8)))
  draw.merge-path(
    fill: gray, {
    draw.arc((), start: 70deg, stop: 110deg, radius: 12, name: "upper-layer")
    draw.line((), (rel: (0, -2)))
    draw.arc((), start: 110deg, stop: 70deg, radius: 12, name: "lower-layer")
    draw.line((), (rel: (0, 2)))
    }
  )  

  draw-ground-station()
  draw-satelite(5, 30deg, "satelite1")
  draw-satelite(5, -30deg, "satelite2")
  
  // scintillation-induced signal
  decorations.wave(draw.line("satelite1.tip", ("satelite1.tip", 20%, "ground-station.tip")),  amplitude: .25, start: 0%, stop: 100%, stroke: red, name: "wave1") 
  for (i, (perc, amp)) in (40%,60%,80%,100%).zip((.125,0.25,0.55,.18)).enumerate() {
    decorations.wave(draw.line("wave"+str(i + 1)+".end", ("satelite1.tip", perc, "ground-station.tip")), amplitude: amp, start: 0%, stop: 100%, stroke: red, name: "wave"+str(i + 2))
  }
  decorations.wave(draw.line("satelite2.tip", "ground-station.tip"), 
  // to scintillation
  amplitude: .25, start: 0%, stop: 100%, stroke: blue)
})

image

In this not-so-minimal working example, a satellite is a set of elements (line(), rect(), circle(), ...) that is grouped and is drawn with the function draw-satelite(height, angle, name), which translates the satellite antenna's tip in polar coordinates and with respect to the ground station antenna's tip.

Here, using polar coordinates to translate/shift it makes total sense as we always think about satellite positioning in terms of radial distance from the ground station and the zenith angle (or, equivalently, the elevation angle):

image

Of course we can came up with workarounds that work (you see that, in my case, I used trigonometry to obtain the same result). But again, translating in polar coordinates is the most intuitive way to go.

@tapyu
Copy link
Contributor Author

tapyu commented May 22, 2024

Didn't we previously allow passing coordinates to translate but changed it in favour of set-origin?

Well, I don't know, but in my POV it is an error. Being able to set the origin in polar coordinates doesn't free us to want to translate an object in polar coordinates with respect to that origin.

This is clear in my previous example, where we set the origin to the ground station antenna's tip, but we want to translate the satellites in polar coordinates with respect to that new origin.

@tapyu tapyu changed the title [feature request] Overload the translate input vector argument to handle different formats [feature request] translate() in polar coordinates May 22, 2024
@tapyu
Copy link
Contributor Author

tapyu commented Jun 25, 2024

So, can we finally agree that it is useful to translate in polar coordinates? 👀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants