Equation-driven smoothly shaded concentric shapes

2019-02-02 06:34发布

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

2条回答
爷的心禁止访问
2楼-- · 2019-02-02 07:04

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.

查看更多
甜甜的少女心
3楼-- · 2019-02-02 07:27

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.

查看更多
登录 后发表回答