Equation-driven smoothly shaded concentric shapes

2019-02-02 07:16发布

问题:

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

  • Use a library such as http://code.google.com/p/jmathplot/
  • Use GNUPlot
  • Use R
  • Plot using Wolfram Alpha, use ImageMagick to create smaller concentric versions

回答1:

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:

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.



回答2:

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.