Equation-driven smoothly shaded concentric shapes
Asked Answered
L

2

20

Background

Looking to create interesting video transitions (in grayscale).

Problem

Given equations that represent a closed, symmetrical shape, plot the outline and concentrically shade the shape towards its centre.

Example

Consider the following equations:

x = 16 * sin(t)^3
y = 13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t)
t = [0:2 * pi]

When plotted:

When shaded, it would resemble (not shown completely shaded, but sufficient to show the idea):

Notice that shading is darkest on the outside (e.g., #000000 RGB hex), then lightens as it fills to the centre. The centre would be a white (e.g., #FFFFFF) dot.

Questions

  1. What would be the most expedient way to produce high-resolution, concentrically shaded grayscale images, such as the shaded heart above?
  2. What are such closed, symmetrical shapes formally called?

Thank you!

Ideas

Latea answered 1/7, 2011 at 1:41 Comment(1)
This was the first of two popular questions regarding "how to plot a heart". I suspect the respondents to the second question did not know of this one when they responded (at least I didn't). So if you want other approaches you might also want to look at: https://mcmap.net/q/389457/-plot-a-heart-in-r-duplicateReprieve
I
32

Try this in R:

# create palette
greyScale <- colorRampPalette(c("black","white"))

# function to draw shape
plotHeart <- function(r, col){
  t <- seq(0,2*pi,length.out=100)
  x <- r*sin(t)^3
  y <- (13*r/16)*cos(t) - (5*r/16)*cos(2*t) - (2*r/16)*cos(3*t) - (r/16)*cos(4*t)
  polygon(x,y,col=col,border=NA)
}



# create new plot canvas
plot.new()
# limits are approximate here
plot.window(xlim=c(-16,16),ylim=c(-16,13))

# use mapply to loop
mapply(plotHeart,seq(16,0,length.out=100),greyScale(100))

Which results in:

Filled heart plot

This works by repeated drawing filled polygons of decreasing size and different colour atop of one another. To answer your questions:

(1) This was produced by my machine (a modest Core 2 duo laptop) in 0.09 seconds. They may be other languages/implementations that are faster, but this seems quick enough to me.

(2) A planar shape made up of lines which do not cross other is usually called a simple polygon.

Ibiza answered 1/7, 2011 at 10:30 Comment(1)
@Dave Jarvis I've added a bit more to answer your questions more directly. This method is pretty general - you just need to supply a different function to draw the shape and make sure it has a scale parameter (the r in my function). The equations you supplied for the heart plot are known as parametric equations.Ibiza
Y
1

Using 2D Graphics, this example alters the transparency of concentric circles using drawOval() to achieve a similar effect, but the approach can be extended to draw() any class implementing the Shape interface. The createTransformedShape() method of AffineTransform may be used to translate and scale the outline concentrically.

Yachtsman answered 1/7, 2011 at 3:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.