This is my first attempt to create some 2D Strange Attractor. My code is based on a blogpot from Will R. Chase. I tried to change his code to incorporate some formulas described on Softology’s Blog. So apparently, strange attractors are created by repeating (or iterating) a formula over and over again and using the result at each iteration to plot a point. The result of each iteration is fed back into the equation. After millions of points have been plotted fractal structures appear. The repeated points fall within a basin of attraction (they are attracted to the points that make up these shapes). I stole this entire explanation. Anyways, let’s go!
I will start by trying to create some pretty Fractal Dream Attractors. They were discovered by Clifford A Pickover and discussed in his book “Chaos in Wonderland”.
library(ggplot2)
## Warning: Paket 'ggplot2' wurde unter R Version 4.1.3 erstellt
library(dplyr)
## Warning: Paket 'dplyr' wurde unter R Version 4.1.3 erstellt
##
## Attache Paket: 'dplyr'
## Die folgenden Objekte sind maskiert von 'package:stats':
##
## filter, lag
## Die folgenden Objekte sind maskiert von 'package:base':
##
## intersect, setdiff, setequal, union
#ggplot theme blank canvas
opt = theme(legend.position = "none",
panel.background = element_rect(fill="black"),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank())
#attractor function
createTrajectory <- function(n, x0, y0, a, b, c, d)
{
#pre-initialize vectors of length n
x <- vector(mode = "numeric", length = n)
y <- vector(mode = "numeric", length = n)
#starting values
x[1] <- x0 #x and y both start at 1
y[1] <- y0
#fill vectors with values
for (i in 2:n) {
x[i] <- sin(y[i-1]*b)+c*sin(x[i-1]*b)
y[i] <- sin(x[i-1]*a)+d*sin(y[i-1]*b)
}
#make dataframe
data.frame(x = x, y = y)
}
#constants
a=-1.1554 #must be between -3 and +3
b=-2.3419 #must be between -3 and +3
c=-1.9799 #must be between -0.5 and +1.5
d=2.1828 #must be between -0.5 and +1.5
#calculate positions and plot
df=createTrajectory(2000000, 0.1, 0.1, a, b, c, d)
attractor1 <- ggplot(df, aes(x, y)) + geom_point(color="#ffffff", shape=46, alpha=.05) + opt
attractor1
#ggsave("attractor1.png", attractor1, width = 30, height = 20, units = "in")
library(ggplot2)
library(dplyr)
#ggplot theme blank canvas
opt = theme(legend.position = "none",
panel.background = element_rect(fill="black"),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank())
#attractor function
createTrajectory <- function(n, x0, y0, a, b, c, d)
{
#pre-initialize vectors of length n
x <- vector(mode = "numeric", length = n)
y <- vector(mode = "numeric", length = n)
#starting values
x[1] <- x0 #x and y both start at 1
y[1] <- y0
#fill vectors with values
for (i in 2:n) {
x[i] <- sin(y[i-1]*b)+c*sin(x[i-1]*b)
y[i] <- sin(x[i-1]*a)+d*sin(y[i-1]*b)
}
#make dataframe
data.frame(x = x, y = y)
}
#constants
a=-0.966918 #must be between -3 and +3
b=2.879879 #must be between -3 and +3
c=0.765145 #must be between -0.5 and +1.5
d=0.744728 #must be between -0.5 and +1.5
#calculate positions and plot
df=createTrajectory(1000000, 0.1, 0.1, a, b, c, d)
ggplot(df, aes(x, y)) + geom_point(color="#ffffff", shape=46, alpha=.05) + opt
library(ggplot2)
library(dplyr)
#ggplot theme blank canvas
opt = theme(legend.position = "none",
panel.background = element_rect(fill="black"),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank())
#attractor function
createTrajectory <- function(n, x0, y0, a, b, c, d)
{
#pre-initialize vectors of length n
x <- vector(mode = "numeric", length = n)
y <- vector(mode = "numeric", length = n)
#starting values
x[1] <- x0 #x and y both start at 1
y[1] <- y0
#fill vectors with values
for (i in 2:n) {
x[i] <- sin(y[i-1]*b)+c*sin(x[i-1]*b)
y[i] <- sin(x[i-1]*a)+d*sin(y[i-1]*b)
}
#make dataframe
data.frame(x = x, y = y)
}
#constants
a=-1.9956 #must be between -3 and +3
b=-1.4528 #must be between -3 and +3
c=-1.6206 #must be between -0.5 and +1.5
d=0.8517 #must be between -0.5 and +1.5
#calculate positions and plot
df=createTrajectory(9000000, 0.1, 0.1, a, b, c, d)
attractor3 <- ggplot(df, aes(x, y)) + geom_point(color="#ffffff", shape=46, alpha=.05) + opt
attractor3
ggsave("attractor3.png", attractor3, width=20, height=20, units="in")
I want to colour my second attractor. I use the code provided by Will.
#install.packages("BiocManager")
#BiocManager::install("EBImage")
library(EBImage)
library(tidyverse)
## Warning: Paket 'tidyverse' wurde unter R Version 4.1.3 erstellt
## Warning: Paket 'tibble' wurde unter R Version 4.1.3 erstellt
## Warning: Paket 'tidyr' wurde unter R Version 4.1.3 erstellt
## Warning: Paket 'readr' wurde unter R Version 4.1.3 erstellt
## Warning: Paket 'purrr' wurde unter R Version 4.1.3 erstellt
## Warning: Paket 'stringr' wurde unter R Version 4.1.3 erstellt
## Warning: Paket 'forcats' wurde unter R Version 4.1.3 erstellt
## Warning: Paket 'lubridate' wurde unter R Version 4.1.3 erstellt
## -- Attaching core tidyverse packages ------------------------ tidyverse 2.0.0 --
## v forcats 1.0.0 v stringr 1.5.0
## v lubridate 1.9.2 v tibble 3.2.1
## v purrr 1.0.1 v tidyr 1.3.0
## v readr 2.1.4
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x EBImage::combine() masks dplyr::combine()
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
## x purrr::transpose() masks EBImage::transpose()
## i Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
#read in the image and convert to greyscale
img <- readImage("attractor3.png")
gray <- channel(img, "gray")
#map the color palette to the image
img_col <- colormap(gray, viridis::magma(256))
display(img_col, method = "raster")
#when you are satisfied with the image, save it
writeImage(img_col, "attractor_3_colour.png")
Next I want to work on creating some Johnny Svensson Attractors.
library(ggplot2)
library(dplyr)
#ggplot theme blank canvas
opt = theme(legend.position = "none",
panel.background = element_rect(fill="black"),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank())
#attractor function
createTrajectory <- function(n, x0, y0, a, b, c, d) {
#pre-initialize vectors of length n
x <- vector(mode = "numeric", length = n)
y <- vector(mode = "numeric", length = n)
#starting values
x[1] <- x0 #x and y both start at 1
y[1] <- y0
#fill vectors with values
for (i in 2:n) {
x[i] <- d*sin(x[i-1]*a)-sin(y[i-1]*b)
y[i] <- c*cos(x[i-1]*a)+cos(y[i-1]*b)}
#make dataframe
data.frame(x = x, y = y)
}
#constants (must all be between -3 and 3)
a=-1.9956
b=-1.4528
c=-1.6206
d=0.8517
#calculate positions and plot
df=createTrajectory(9000000, 0.1, 0.1, a, b, c, d)
jsattractor1 <- ggplot(df, aes(x, y)) + geom_point(color="#ffffff", shape=46, alpha=.05) + opt
jsattractor1
ggsave("jsattractor1.png", jsattractor1, width=20, height=20, units="in")
#install.packages("BiocManager")
#BiocManager::install("EBImage")
library(EBImage)
library(tidyverse)
#read in the image and convert to greyscale
img <- readImage("jsattractor1.png")
gray <- channel(img, "gray")
#map the color palette to the image
img_col <- colormap(gray, viridis::magma(256))
#display(img_col, method = "raster")
#when you are satisfied with the image, save it
writeImage(img_col, "jsattractor_1_colour.png")