Нарисуйте многоугольник такого цвета в R или Matlab.

http://www.texample.net/tikz/examples/lindenmayer-systems/ введите здесь описание изображения

Мой пример кода, показанный ниже, я не знаю, как раскрасить оттенок.

plot.koch <- function(k,col="blue"){ 
  plot(0,0,xlim=c(0,1), ylim=c(-sqrt(3)/6,sqrt(3)/2), asp = 1,type="n",xlab="", ylab="")
  plotkoch <- function(x1,y1,x2,y2,n){
    if (n > 1){
      plotkoch(x1,y1,(2*x1+x2)/3,(2*y1+y2)/3,n-1); 
      plotkoch((2*x1+x2)/3,(2*y1+y2)/3,(x1+x2)/2-(y1-y2)*sqrt(3)/6,(y1+y2)/2-(x2-x1) *sqrt(3)/6,n-1);
      plotkoch((x1+x2)/2-(y1-y2)*sqrt(3)/6,(y1+y2)/2-(x2-x1)*sqrt(3)/6,(2*x2+x1)/3,(2 *y2+y1)/3,n-1); 
      plotkoch((2*x2+x1)/3,(2*y2+y1)/3,x2,y2,n-1)
    }    
    else { 
      x=c(x1,(2*x1+x2)/3,(x1+x2)/2-(y1-y2)*sqrt(3)/6,(2*x2+x1)/3,x2); 
      y=c(y1,(2*y1+y2)/3,(y1+y2)/2-(x2-x1)*sqrt(3)/6,(2*y2+y1)/3,y2); 
      polygon(x,y,type="l",col=col) 
    }
  }
  plotkoch(0,0,1,0,k) 
  plotkoch(0.5,sqrt(3)/2,0,0,k) 
  plotkoch(1,0,0.5,sqrt(3)/2,k)
}
  plot.koch(3, col=3)  

person expression    schedule 10.02.2015    source источник


Ответы (4)


Вот метод, использующий пространственные объекты в R с пакетами sp, rgeos и raster в сочетании.

  1. Небольшие изменения в функции для возврата пользователю координат x,y (и в правильном порядке):

    koch <- function(k) { 
      yy <- xx <- numeric(0)
      Koch <- function(x1, y1, x2, y2, n) {
        if (n > 1){
          Koch(x1, y1, (2*x1+x2)/3, (2*y1+y2)/3, n-1); 
          Koch((2*x1+x2)/3, (2*y1+y2)/3, (x1+x2)/2-(y1-y2)*sqrt(3)/6, 
               (y1+y2)/2-(x2-x1) *sqrt(3)/6, n-1);
          Koch((x1+x2)/2-(y1-y2)*sqrt(3)/6, (y1+y2)/2-(x2-x1)*sqrt(3)/6, 
               (2*x2+x1)/3, (2 *y2+y1)/3, n-1); 
          Koch((2*x2+x1)/3, (2*y2+y1)/3, x2, y2, n-1)
        }    
        else { 
          x <- c(x1, (2*x1+x2)/3, (x1+x2)/2-(y1-y2)*sqrt(3)/6, (2*x2+x1)/3, x2); 
          xx <<- c(xx, x)
          y <- c(y1, (2*y1+y2)/3, (y1+y2)/2-(x2-x1)*sqrt(3)/6, (2*y2+y1)/3, y2); 
          yy <<- c(yy, y)
         }
      }
      Koch(0, 0, 1, 0, k)
      Koch(1, 0, 0.5, sqrt(3)/2, k)
      Koch(0.5, sqrt(3)/2, 0, 0, k) 
      xy <- data.frame(x=xx, y=yy)
      rbind(unique(xy), xy[1, ])
    }
    
  2. Создайте цветовую шкалу:

    colr <- colorRampPalette(hcl(h=seq(0, 360, len=100), c=100))
    
  3. Используйте функцию koch для получения вершин:

    xy <- koch(4)
    
  4. Загрузите пространственные пакеты и создайте SpatialPolygons объект из фрактала и начертите его один раз, чтобы настроить область построения.

    library(sp)
    library(rgeos)
    library(raster)
    
    poly <- SpatialPolygons(list(Polygons(list(Polygon(xy)), 1)))
    plot(poly)
    
  5. Постройте серию сегментов с желаемым началом и достаточно большим радиусом, чтобы покрыть фрактальный многоугольник (здесь мы используем радиус r <- 1).

    r <- 1
    mapply(function(theta, col) {
      segments(0.5, 0.3, 0.5 + r*cos(theta), 0.3 + r*sin(theta), lwd=3, col=col) 
    }, seq(0, 360, length=1000)*pi/180, colr(1000))       
    
  6. Создайте второй многоугольник разницы между областью графика и фрактальным многоугольником и постройте его (с col='white'), чтобы замаскировать нежелательную область градиента.

    plot(gDifference(as(extent(par('usr')), 'SpatialPolygons'), poly), 
         col='white', border='white', add=TRUE)
    
  7. Постройте многоугольник еще раз.

    plot(poly, add=TRUE)
    

введите здесь описание изображения

person jbaums    schedule 10.02.2015

Вот моя попытка решить ваш вопрос. В настоящее время он рисует цвет также за пределами снежинки. Если вы можете выяснить, находятся ли точки внутри или снаружи снежинки, вы сможете просто удалить внешние точки в df_fill. Здесь я сначала создаю data.frame, используемый для построения полигона. Затем я создаю data.frame для цвета фона. И, наконец, я использую ggplot2 для построения данных.

# creating relevant data
data.koch <- function(k){ 
  df <- data.frame(x = 0, 
                   y = 0, 
                   grp = 0)
  plotkoch <- function(x1, y1, x2, y2, n, data){
    if (n==1) {
      x=c(x1,(2*x1+x2)/3,(x1+x2)/2-(y1-y2)*sqrt(3)/6,(2*x2+x1)/3,x2) 
      y=c(y1,(2*y1+y2)/3,(y1+y2)/2-(x2-x1)*sqrt(3)/6,(2*y2+y1)/3,y2) 
      df <- rbind(data, data.frame(x, y, grp=max(data$grp)+1))
    }
    if (n > 1){
      df <- plotkoch(x1,y1,(2*x1+x2)/3,(2*y1+y2)/3,n-1, data = data)
      df <- plotkoch((2*x1+x2)/3,(2*y1+y2)/3,(x1+x2)/2-(y1-y2)*sqrt(3)/6,(y1+y2)/2-(x2-x1) *sqrt(3)/6,n-1, data=df)
      df <- plotkoch((x1+x2)/2-(y1-y2)*sqrt(3)/6,(y1+y2)/2-(x2-x1)*sqrt(3)/6,(2*x2+x1)/3,(2 *y2+y1)/3,n-1, data=df) 
      df <- plotkoch((2*x2+x1)/3,(2*y2+y1)/3,x2,y2,n-1, data=df)
    }    
    return(df)
  }
  df <- plotkoch(0,0,1,0,k, data = df) 
  df <- plotkoch(0.5,sqrt(3)/2,0,0,k, data = df) 
  df <- plotkoch(1,0,0.5,sqrt(3)/2,k, data = df)
  return(df)
}
# plotting functon
plot.koch <- function(k){
  stopifnot(require(ggplot2))
  if (is.data.frame(k)) df <- k
  else df <- data.koch(k)
  # filling data (CHANGE HERE TO GET ONLY INSIDE POINTS)
  l <- 500
  df_fill <- expand.grid(x=seq(0, 1, length=l), 
                         y=seq(-sqrt(3)/6, sqrt(3)/2, length=l))
  df_fill[, "z"] <- atan2(-df_fill[, "y"] + sqrt(3)/6, df_fill[, "x"] - 0.5) + pi/2
  df_fill[df_fill[, "z"] < 0, "z"] <- df_fill[df_fill[, "z"] < 0, "z"] + 2*pi
  # plotting
  ggplot(df, aes(x, y, group=grp)) + 
    geom_raster(data = df_fill, 
                aes(fill=z, group=NULL), 
                hjust = 0,
                vjust = 0,
                linetype='blank') + 
    geom_path(data=df, size=1) +
    scale_fill_gradientn(colours = rainbow(30), guide = 'none') + 
    scale_x_continuous(name = '', limits = c(0, 1), expand=c(0, 0)) + 
    scale_y_continuous(name = '', limits = c(-sqrt(3)/6,sqrt(3)/2), expand=c(0, 0)) +
    coord_fixed() +
    theme_bw() +
    theme(axis.line = element_blank(), 
          panel.grid = element_blank(), 
          axis.ticks = element_blank(), 
          axis.text = element_blank())
}
#
p <- plot.koch(4)
print(p)

вывод из plot.koch(4)

person shadow    schedule 10.02.2015

Я бы сделал это так:

  1. для любого нарисованного пикселя получить его позицию x,y
  2. вычислить angle=atan2(y-y0,x-x0)

    где x0,y0 — среднее положение снежинки Коха

  3. вычислить цвет на основе угла

    если вы используете HSV, то hue=angle и вычислите целевое значение цвета (я предполагаю, что RGB). Если вам нужны цвета видимого спектра, вы можете попробовать мои:

    Просто преобразуйте диапазон углов angle=<0,2*Pi> [rad] в длину волны l=<400,700> [nm] так:

    l = 400.0 + (700.0-400.0)*angle/(2.0*M_PI)
    
  4. рендеринг пикселя

[Примечания]

не используя ни R, ни Matlab, поэтому вам нужно написать код самостоятельно. Угол может потребовать некоторого смещения, чтобы соответствовать вашей системе координат, например:

const angle0=???; // some shift constant [rad]
angle+=angle0; // or angle=angle0-angle; if the direction is oposite
if (angle>=2.0*M_PI) angle-=2.0*M_PI;
if (angle<      0.0) angle+=2.0*M_PI;

Если вы рисуете это как многоугольник, вам нужно вычислять цвет для вершины, а не для пикселя, но тогда вы можете столкнуться с проблемами, потому что это не выпуклый многоугольник. Итак, как обеспечить средний цвет??? Боюсь, вам придется использовать какую-то триангуляцию, потому что простой треугольный веер не сработает...

Единственное, что очевидно, это заполнить цветом все пространство, а затем нарисовать контур черным цветом, а затем залить все нечерные пиксели снаружи белым цветом.

person Spektre    schedule 10.02.2015

Это мое решение с пакетом сетки.

##data
  koch <- function(k) {
        yy <- xx <- numeric(0)
        Koch <- function(x1, y1, x2, y2, n) {
            if (n > 1) {
                Koch(x1, y1, (2 * x1 + x2)/3, (2 * y1 + y2)/3, n - 1)
                Koch((2 * x1 + x2)/3, (2 * y1 + y2)/3, (x1 + x2)/2 - (y1 - 
                  y2) * sqrt(3)/6, (y1 + y2)/2 - (x2 - x1) * sqrt(3)/6, 
                  n - 1)
                Koch((x1 + x2)/2 - (y1 - y2) * sqrt(3)/6, (y1 + y2)/2 - 
                  (x2 - x1) * sqrt(3)/6, (2 * x2 + x1)/3, (2 * y2 + y1)/3, 
                  n - 1)
                Koch((2 * x2 + x1)/3, (2 * y2 + y1)/3, x2, y2, n - 1)
            } else {
                x <- c(x1, (2 * x1 + x2)/3, (x1 + x2)/2 - (y1 - y2) * sqrt(3)/6, 
                  (2 * x2 + x1)/3, x2)
                xx <<- c(xx, x)
                y <- c(y1, (2 * y1 + y2)/3, (y1 + y2)/2 - (x2 - x1) * sqrt(3)/6, 
                  (2 * y2 + y1)/3, y2)
                yy <<- c(yy, y)
            }
        }
        Koch(0, 0, 1, 0, k)
        Koch(1, 0, 0.5, sqrt(3)/2, k)
        Koch(0.5, sqrt(3)/2, 0, 0, k)
        xy <- data.frame(x = (xx - min(xx))/(max(xx) - min(xx)), y = (yy - 
            min(yy))/(max(yy) - min(yy)))
        rbind(unique(xy), xy[1, ])
    }
xy <- koch(5)
##Plot
library(grid)
grid.newpage()
pushViewport(dataViewport(xy$x, xy$y), plotViewport(c(1, 1, 1, 1)))
    for (i in 1:nrow(xy)) {
       grid.path(x = c(xy[i, 1], xy[i + 1, 1], mean(xy$x)), 
                 y = c(xy[i, 2], xy[i + 1, 2], mean(xy$y)), 
                 gp = gpar(col = rainbow(nrow(xy))[i], 
                           fill = rainbow(nrow(xy))[i]))
        }

Вот изображение

person Dr Duck    schedule 02.12.2016