Farbfetzen / fractalplotr

Make beautiful fractals with R
Other
0 stars 0 forks source link

Coordinate conversion #17

Closed Farbfetzen closed 5 years ago

Farbfetzen commented 5 years ago

Provide an easy way to specify coordinates for mandelbrots and related fractals. There should be several valid ways for users to specify coordinates:

Make it optional that the aspect ratio ist 1:1. If the user wants a skewed image then let them. But the default should be a ratio of 1:1.

Farbfetzen commented 5 years ago

Some related and very old code from my first working mandelbrot script:

adjust_im_lim <- function(width, height, re_lim, im_lim) {
  # Adjust im_lim to preserve the correct aspect ratio and prevent distortion.
  re_units_per_pixel <- abs(diff(re_lim)) / width
  im_radius <- complex(
    real = 0,
    imaginary = re_units_per_pixel * height / 2
  )
  im_center <- mean(im_lim)
  c(im_center - im_radius, im_center + im_radius)
}

adjust_re_lim <- function(width, height, re_lim, im_lim) {
  # Adjust re_lim to preserve the correct aspect ratio and prevent distortion.
  im_units_per_pixel <- abs(diff(im_lim)) / height
  re_radius <- im_units_per_pixel * width / 2
  re_center <- mean(re_lim)
  c(re_center - re_radius, re_center + re_radius)
}

adjust_both <- function(width, height, re_lim, im_lim) {
  # Adjust re_lim and im_lim at the same time to preserve the correct aspect
  # ratio and prevent distortion.
  re_units_per_pixel <- abs(diff(re_lim)) / width
  im_units_per_pixel <- abs(diff(im_lim)) / height
  mean_units_per_pixel <- mean(c(re_units_per_pixel, im_units_per_pixel))

  im_radius <- complex(
    real = 0,
    imaginary = mean_units_per_pixel * height / 2
  )
  im_center <- mean(im_lim)
  im_lim <- c(im_center - im_radius, im_center + im_radius)

  re_radius <- mean_units_per_pixel * width / 2
  re_center <- mean(re_lim)
  re_lim <- c(re_center - re_radius, re_center + re_radius)

  list(re_lim=re_lim, im_lim=im_lim)
}

And some argument checking and adjusting:

if (is.null(re_lim)) {
    if (!is.null(center)) {
        if (is.null(re_width)) {
            re_width <- diff(standard_limits[[fractal_type]][["re_lim"]])
            re_lim <- c(center[1] - re_width/2, center[1] + re_width/2)
        } else {
            re_lim <- c(center[1] - re_width/2, center[1] + re_width/2)
        }
    } else {
        if (!is.null(re_width)) {
            re_center <- mean(standard_limits[[fractal_type]][["re_lim"]])
            re_lim <- c(re_center - re_width/2, re_center + re_width/2)
        } else {
            print("Using standard values for re_lim.")
            re_lim <- standard_limits[[fractal_type]][["re_lim"]]
        }
    }
}
if (is.null(im_lim)) {
    if (!is.null(center)) {
        if (is.null(im_height)) {
            im_height <- diff(standard_limits[[fractal_type]][["im_lim"]])
            im_lim <- c(center[2] - im_height/2, center[2] + im_height/2)
        } else {
            im_lim <- c(center[2] - im_height/2, center[2] + im_height/2)
        }
    } else {
        if (!is.null(im_height)) {
            im_center <- mean(standard_limits[[fractal_type]][["im_lim"]])
            im_lim <- c(im_center - im_height/2, im_center + im_height/2)
        } else {
            print("Using standard values for im_lim.")
            im_lim <- standard_limits[[fractal_type]][["im_lim"]]
        }
    }
}
if (!startsWith("none", adjust)) {
    if (startsWith("real", adjust)) {
        re_lim <- adjust_re_lim(width, height, re_lim, im_lim)
    } else if (startsWith("imaginary", adjust)) {
        im_lim <- adjust_im_lim(width, height, re_lim, im_lim)
    } else if(startsWith("both", adjust)) {
        new_limits <- adjust_both(width, height, re_lim, im_lim)
        re_lim <- new_limits$re_lim
        im_lim <- new_limits$im_lim
    }
}
Farbfetzen commented 5 years ago

Don't use any "adjust" parameters. Just check which parameters are missing and then form the matrix using it. For example if the user enters a width and height along with left, right, top and bottom then use that without complaining. But warn the user in the documentation.

Farbfetzen commented 5 years ago

Move the checking and conversion of the coordinate arguments into a separate function inside the file where complex_plane sits. This is because more than just the mandelbrot will use it.