r-lib / marquee

Markdown Parser and Renderer for R Graphics
https://marquee.r-lib.org
Other
85 stars 1 forks source link

add `xDetails()`/`yDetails()` methods #12

Closed teunbrand closed 7 months ago

teunbrand commented 7 months ago

This PR aims to fix #11.

This was less complicated than anticipated, because the relevant corner points were already calculated somewhere.

Example from issue; the points on the bounding box are now found correctly:

devtools::load_all("~/packages/marquee/")
#> ℹ Loading marquee

label <- "Lorem ipsum dolor sit amet, consectetur 
adipiscing elit. In hendrerit metus quam, 
sed rutrum nulla feugiat consequat. Sed eu 
pulvinar purus, vel placerat metus."

theta <- seq(0, 315, by = 15)

mq <- marquee_grob(
  label, classic_style(), 
  angle = 45, x = 0.5, y = 0.5, hjust = 0.5, vjust = 0.5
)

grid.newpage()
grid.draw(mq)

x <- grobX(mq, theta)
y <- grobY(mq, theta)

grid.points(x = x, y = y, gp = gpar(col = 'red'))

Created on 2024-04-30 with reprex v2.1.0

thomasp85 commented 7 months ago

Be aware that everything in makeContext is vectorised. Does your PR work correctly when containing multiple strings at different positions?

teunbrand commented 7 months ago

x/yDetails.points() computes a convex hull around the points, so it does a good job when length(text) > 1. This differs somewhat from textGrob() which will just calculate a rectangle containing all the text, but this argueably is more of a limitation of textGrob().

Demo (hjust of 2nd string looks a bit off):

devtools::load_all("~/packages/marquee/")
#> ℹ Loading marquee

label <- c("Lorem ipsum dolor sit amet, consectetur 
adipiscing elit. In hendrerit metus quam, 
sed rutrum nulla feugiat consequat.", "Sed eu 
pulvinar purus, vel placerat metus.")

theta <- seq(0, 315, by = 15)

mq <- marquee_grob(
  label, classic_style(), 
  angle = 45, x = c(0.3, 0.7), y = 0.5, hjust = 0.5, vjust = 0.5
)

grid.newpage()
grid.draw(mq)

x <- grobX(mq, theta)
y <- grobY(mq, theta)

grid.points(x = x, y = y, gp = gpar(col = 'red'))

And a regular text grob:

txt <- textGrob(label, x = c(0.3, 0.7), rot = 45)

grid.newpage()
grid.draw(txt)

x <- grobX(txt, theta)
y <- grobY(txt, theta)

grid.points(x = x, y = y, gp = gpar(col = 'red'))

Created on 2024-04-30 with reprex v2.1.0

teunbrand commented 7 months ago

Sorry I wasn't thinking clearly. Yes, you're right, the origin should be recycled along with the corner positions. The example is a bit unlucky in that it didn't show the problem.

thomasp85 commented 7 months ago

Thanks