Fractals/Computer graphic techniques/2D/plane

From Wikibooks, open books for an open world
Jump to navigation Jump to search

2D plane


Geometry[edit | edit source]

  • Euclidean[1]
  • non-Euclidean[2]
    • hyperbolic
    • eliptic
Differences between Euclidean and non-Eucl. geometries: behavior of lines with a common perpendicular in each of the three types of geometry

visualisation[edit | edit source]

Viewport (visible part of the plane )[edit | edit source]

A viewport is a polygon viewing region in computer graphics.[3]


parameter files[edit | edit source]

Parameters can be read from both parameter and image files :[4]

Reading parameters[edit | edit source]

/*
  from  gui main.c
  https://gitorious.org/maximus/book/source/47ce485c4266b3d5fc62f685f001ce7606ce426f:
  by 
  http://mathr.co.uk/blog/

  loads txt file with parameters
  http://qualapps.blogspot.com/2009/01/unicode-bom-handling-in-c-run-time.html
  http://www.joelonsoftware.com/articles/Unicode.html
  http://programmers.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful
  http://utf8everywhere.org/
  http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451/The-Basics-of-UTF8.htm
  http://stackoverflow.com/questions/2113270/how-to-read-unicode-utf-8-binary-file-line-by-line
  http://www.cl.cam.ac.uk/~mgk25/unicode.html

  gcc l.c -lmpfr -lgmp -Wall

*/
#include <stdio.h>
#include <stdlib.h> // malloc
#include <string.h> // strncmp
#include <ctype.h> // isascii
#include <mpfr.h>

struct view {
  mpfr_t cx, cy, radius, pixel_spacing;
};

static struct view *view_new() {
  struct view *v = malloc(sizeof(struct view));
  mpfr_init2(v->cx, 53);
  mpfr_init2(v->cy, 53);
  mpfr_init2(v->radius, 53);
  mpfr_init2(v->pixel_spacing, 53);
  return v;
}

static void view_delete(struct view *v) {
  mpfr_clear(v->cx);
  mpfr_clear(v->cy);
  mpfr_clear(v->radius);
  mpfr_clear(v->pixel_spacing);
  free(v);
}

//http://stackoverflow.com/questions/5457608/how-to-remove-a-character-from-a-string-in-c?rq=1
// Fabio Cabral
void removeChar(char *str, char garbage) {

    char *src, *dst;
    for (src = dst = str; *src != '\0'; src++) {
        *dst = *src;
        if (*dst != garbage) dst++;
    }
    *dst = '\0';
}

// https://en.wikipedia.org/wiki/Serialization
// read data from file 
static int deserialize(const char *filename) {

  // open file in a text mode 
  FILE *in = fopen(filename, "r");

  if (in) {
    printf( "file %s opened\n", filename);
    char *line = 0;
    size_t linelen = 0;
    ssize_t readlen = 0; // bytes_read = length of the line 
    
    // read line 
    while (-1 != (readlen = getline(&line, &linelen, in)))     
      {
        // 
	if (readlen && line[readlen-1] == '\n') { 
	  line[readlen - 1] = 0; }

	// remove BOM 
        while  (! isascii(line[0])) 
               {printf(" removed non-printing char = %c ( non -ASCII char ) = %3d  (signed 8 bit) = %u (unsigned 8 bit) =  0x%.2X (hexadecimal) \n", line[0], line[0], (unsigned char) line[0], (unsigned char) line[0]);
                removeChar(line,line[0]);
                }
                
       
	// size 
	if (0 == strncmp(line, "size ", 5)) 
	  {

	    printf( "size line found :");
    
	    int w = 0, h = 0;
	    sscanf(line + 5, "%d %d\n", &w, &h);
	    printf( "size of image in pixels : width = %d   ; height = %d \n", w,h);
	    // resize_image(w, h); // FIXME TODO make this work...
	  } 
         
        //  view
        else if (0 == strncmp(line, "view ", 5)) 
	  {
	    printf( "view line found : \n");
	    int p = 53;
	    char *xs = malloc(readlen);   
	    char *ys = malloc(readlen);
	    char *rs = malloc(readlen);
	    sscanf(line + 5, "%d %s %s %s", &p, xs, ys, rs);

	    struct view *v = view_new();
	    mpfr_set_prec(v->cx, p);
	    mpfr_set_prec(v->cy, p);
	    mpfr_set_str(v->cx, xs, 0, GMP_RNDN);
	    mpfr_set_str(v->cy, ys, 0, GMP_RNDN);
	    mpfr_set_str(v->radius, rs, 0, GMP_RNDN);
	    //
	    printf ("precision p  =  %d\n", p);
	    printf ("center =  ");
	    mpfr_out_str (stdout, 10, p, v->cx, MPFR_RNDD);
	    printf (" ; ");
	    mpfr_out_str (stdout, 10, p, v->cy, MPFR_RNDD);
	    putchar ('\n');

	    printf ("radius =  ");
	    mpfr_out_str (stdout, 10, p, v->radius, MPFR_RNDD);
	    putchar ('\n');

	    free(xs);
	    free(ys);
	    free(rs);
	    view_delete(v);
        
	  } 
         
	else if (0 == strncmp(line, "ray_out ", 8)) 
	  {
	    printf( "ray_out line found :\n");
	    int p = 53;
	    char *xs = malloc(readlen);
	    char *ys = malloc(readlen);
	    sscanf(line + 8, "%d %s %s", &p, xs, ys);
	    mpfr_t cx, cy;
	    mpfr_init2(cx, p);
	    mpfr_init2(cy, p);
	    mpfr_set_str(cx, xs, 0, GMP_RNDN);
	    mpfr_set_str(cy, ys, 0, GMP_RNDN);
	    free(xs);
	    free(ys);
           
	    mpfr_clear(cx);
	    mpfr_clear(cy);
	  } 
        
        else if (0 == strncmp(line, "ray_in ", 7)) {
	  printf( "ray_in line found : \n");
	  int depth = 1000;
	  char *as = malloc(readlen);
	  sscanf(line + 7, "%d %s", &depth, as);
        
	  free(as);
	} 
      
	else if (0 == strncmp(line, "text ", 20)) {
	  printf( "text line found : \n");
	  //int p = 53;
	  char *xs= malloc(readlen);
	  char *ys = malloc(readlen);
	  char *ss = malloc(readlen);
	  sscanf(line + 20, "%s %s %s \n", xs, ys, ss);
        
       
	  free(xs);
	  free(ys);
	  free(ss);
	}

      
	else if (0 == strncmp(line, "//", 2 )) {
	  printf( "line of comment found : %s\n", line );
        
        }
	else printf( "not-known line found ! Maybe line with BOM ? \n");

      } // while

    free(line);
    fclose(in);
    printf( "file %s closed\n", filename);
    return 0;} 
 
  // if (in)
  else {
    printf( "file %s not opened = error !\n", filename);  
    return 1;}
}

int main (int argc, const char* argv[]) 
{

  if (argc != 2) {
    fprintf(stderr, "program opens text file \n");
    fprintf(stderr, "program input : text file with parameters \n");
    fprintf(stderr, "usage: %s filename\n", argv[0]);
    return 1;
  }

  deserialize(argv[1]);

  return 0;
}

Description[edit | edit source]

Rectangle part of 2D plane can be described by :

  • corners ( 4 real numbers or 2 complex numbers = 2D points)
  • center and :
    • width ( 3 real numbers )
    • magnification
    • radius

"People specify fractal coordinates in many ways. Some people use the coordinates of the upper-left and lower-right visible points, specifying the coordinates as four numbers x1, y1, x2, y2. To set the same viewpoint in XaoS, set the real portion of the center to (x1+x2)/2, the imaginary part of center to (y1+y2)/2, and the radius to the greater of x2-x1 and y2-y1." ( from Xaos doc[5] )

Corners[edit | edit source]

Standard description in Fractint, Ultra Fractal, ChaosPro and Fractal Explorer are corners. For example initial plane for Mandelbrot set is

 Corners:                X                     Y
 Top-l          -2.5000000000000000    1.5000000000000000
 Bot-r           1.5000000000000000   -1.5000000000000000
 Ctr -0.5000000000000000   0.0000000000000000  Mag 6.66666667e-01
 X-Mag-Factor     1.0000   Rotation    0.000   Skew    0.000

Display window of parameter plane has :

  • a horizontal width of 4 (real)
  • a vertical width (height) of 3 (imag)
  • an aspect ratio (proportion) 4/3 ( also in pixels 640/480 so ther is no distorsion)
  • center z=-0.5

See demo par file :

Mandel_Demo        { ; PAR for initialization of Fractint demo
  reset=1900 type=mandel corners=-2.5/1.5/-1.5/1.5 params=0/0 inside=0
  sound=no
  }

For julia set/ dynamic plane has :

Corners:                X                     Y
Top-l          -2.0000000000000000    1.5000000000000000
Bot-r           2.0000000000000000   -1.5000000000000000
Ctr  0.0000000000000000   0.0000000000000000  Mag 6.66666667e-01
X-Mag-Factor     1.0000   Rotation    0.000   Skew    0.000

Description from documentation of Fractint :

CORNERS=[xmin/xmax/ymin/ymax[/x3rd/y3rd]]

Example: corners=-0.739/-0.736/0.288/0.291

Begin with these coordinates as the range of x and y coordinates, rather than the default values of (for type=mandel) -2.0/2.0/-1.5/1.5. When you specify four values (the usual case), this defines a rectangle: x- coordinates are mapped to the screen, left to right, from xmin to xmax, y-coordinates are mapped to the screen, bottom to top, from ymin to ymax. Six parameters can be used to describe any rotated or stretched parallelogram: (xmin,ymax) are the coordinates used for the top-left corner of the screen, (xmax,ymin) for the bottom-right corner, and (x3rd,y3rd) for the bottom-left. Entering just "CORNERS=" tells Fractint to use this form (the default mode) rather than CENTER-MAG (see below) when saving parameters with the [B] command.


int SetPlaneFromCorners(double CxMin , double CxMax, double CyMin , double CyMax){
  
  
  
  Radius = fabs(CyMax-CyMin)/2.0;
  Magnification = 1.0/Radius;
  
  // http://www.purplemath.com/modules/midpoint.htm
  Center = (CxMax+CxMin)/2.0 + I*(CyMax+CyMin)/2.0;
  
    
  return 0; 
 


}

Center and ...[edit | edit source]

 "If you use the center, you can change the zoom level and the plot zooms in/out smoothly on the same center point. " Duncan C). 

magnification[edit | edit source]

Fractint uses Mag ( compare with Xmagfactor)

 CENTER-MAG=[Xctr/Yctr/Mag[/Xmagfactor/Rotation/Skew]]

This is an alternative way to enter corners as a center point and a magnification that is popular with some fractal programs and publications. Entering just "CENTER-MAG=" tells Fractint to use this form rather than CORNERS (see above) when saving parameters with the [B] command. The [TAB] status display shows the "corners" in both forms. When you specify three values (the usual case), this defines a rectangle: (Xctr, Yctr) specifies the coordinates of the center of the image.

Mag indicates the amount of magnification to use. Initial value ( no zoom ) is 6.66666667e-01.

Six parameters can be used to describe any rotated or stretched parallelogram: Xmagfactor tells how many times bigger the x- magnification is than the y-magnification,

Rotation indicates how many degrees the image has been turned.

Skew tells how many degrees the image is leaning over. Positive angles will rotate and skew the image counter-clockwise.

Parameters can be saved to parmfile called fractint.par

width[edit | edit source]

Wolf Jung uses center and width in Mandel:

/* 
   from mndlbrot.cpp  by Wolf Jung (C) 201
   These classes are part of Mandel 5.7, which is free software; you can
   redistribute and / or modify them under the terms of the GNU General
   Public License as published by the Free Software Foundation; either
   version 3, or (at your option) any later version. In short: there is
   no warranty of any kind; you must redistribute the source code as well
*/
void mndlbrot::startPlane(int sg, double &xmid, double &rewidth) const
{  if (sg > 0) 
     { xmid = -0.5; rewidth = 1.6; } // parameter plane
     else { xmid = 0; rewidth = 2.0; } // dynamic plane

width and height[edit | edit source]

to describe plane ( view ) Xaos uses:

  • 4 numbers in scripts
  • 3 numbers in menu

Xaos uses to call it "radius" but it is defind as : the greater of (x2-x1= width) and y2-y1=height."

radius[edit | edit source]

It is very usefull for zooming : fix center and only change radius.

Claude Heiland-Allen[6] use center and radius for parameter plane of complex quadratic polynomial:

Radius is defined as:

  • "the difference in imaginary coordinate between the center and the top of the axis-aligned view rectangle".
  • "px_radius is half the width of the image (in real coordinates)" [7]
view="-0.75 0 1.5" # standard view of parameter plane : center_re, center_im, radius

  // modified code using center and radius to scan the plane 
  int height = 720;
  int width = 1280;
  double dWidth;
  double dRadius = 1.5;
  double complex center= -0.75*I;
  double complex c;
  int i,j;

  double width2; // = width/2.0
  double height2; // = height/2.0
  
  width2 = width /2.0;
  height2 = height/2.0;

complex double coordinate(int i, int j, int width, int height, complex double center, double radius) {
  double x = (i - width /2.0) / (height/2.0);
  double y = (j - height/2.0) / (height/2.0);
  complex double c = center + radius * (x - I * y);
  return c;
}

for ( j = 0; j < height; ++j) {
    for ( i = 0; i < width; ++i) {
      c = coordinate(i, j, width, height, center, dRadius);
      // do smth 
       }
     }

The same in GLSL ( for Shadertoy) :

 
vec2 GiveCoordinate(vec2 center, float radius, vec2 fragCoord, vec3 iResolution)
{
 
  // from pixel to world coordinate   
  // now point (0,0) is left bottom
  // point (iResolution.x, iResolution.y) is right top   
  float x = (fragCoord.x -  iResolution.x/2.0)/ (iResolution.y/2.0);
  float y = (fragCoord.y -  iResolution.y/2.0)/ (iResolution.y/2.0);
  vec2 c = vec2(center.x + radius*x, center.y + radius*y) ;  
  return c ; 
}


Set plane:

 
int SetPlane(complex double center, double radius, double a_ratio){

	ZxMin = creal(center) - radius*a_ratio;	
	ZxMax = creal(center) + radius*a_ratio;	//0.75;
	ZyMin = cimag(center) - radius;	// inv
	ZyMax = cimag(center) + radius;	//0.7;
	return 0;

}

Orientation[edit | edit source]

Check orientation of the plane by marking first quadrant of Cartesian plane :

if (x>0 && y>0) Color=MaxColor-Color;

It should be in upper right position.

Display Aspect ratio[edit | edit source]

The aspect ratio, or more precisely the Display Aspect Ratio (DAR)[8] – the aspect ratio of the image as displayed. For TV:

  • for TV DAR as traditionally 4:3 (a.k.a. Fullscreen)
  • now is 16:9 (a.k.a. Widescreen) now the standard for HDTV

Optimisation[edit | edit source]

Quality[edit | edit source]

Scanning, sampling and decomposition[edit | edit source]

  • Sampling = process of getting a finite number of values from a function, map, image.[12]
  • Spatial sampling ( what happens between samples ? ) : a manually-defined homogeneous grid = uniform sampling
    • 1 pixel approximation = image shows "the set of points in the plane whose distance to the filled Julia set is at most the diameter of a pixel"[13]
  • supersampling[14] = sub-pixel aproximation ( resolution)[15]
  • adaptive sampling = Adaptive Mesh Refinement (AMR)
    • a quadtree decomposition of the complex plane with adaptive refinement gives adaptive approximation
    • Adaptive Subdivision
    • "Mathematica automatically samples more points when needed to create a smooth function visualization"[16]
    • Adaptive Sampling for precise Plotting Math Curve[17]


Criteria for classifications

  • number of passes ( single pass, multiple pass)
  • grid ( regular = uniform / irregular or adaptive )


See :

All the pixels[edit | edit source]

Scan the plane :

  • all pixels ( plane is scanned pixel by pixel )
  • the same pixel size

Here in Lisp

; common lisp. Here float values can be used,  there is no mapping
(loop for y from -1.5 to 1.5 by 0.1 do
      (loop for x from -2.5 to 0.5 by 0.05 do
            (princ (code-char 42))) ; print char
      (format t "~%")) ; new line

and in C

/* c */
/* screen coordinate = coordinate of pixels */      
int iX, iY, 
iXmin=0, iXmax=1000,
iYmin=0, iYmax=1000,
iWidth=iXmax-iXmin+1,
iHeight=iYmax-iYmin+1;

/* world ( double) coordinate = parameter plane*/
const double ZxMin=-5;
const double ZxMax=5;
const double ZyMin=-5;
const double ZyMax=5;

/* */
double PixelWidth=(ZxMax-ZxMin)/iWidth;
double PixelHeight=(ZyMax-ZyMin)/iHeight;
double Zx, Zy,    /* Z=Zx+Zy*i   */
       Z0x, Z0y,  /* Z0 = Z0x + Z0y*i */

 for(iY=0;iY<iYmax;++iY)
      { Z0y=ZyMin + iY*PixelHeight; /* mapping from screen to world; reverse Y  axis */
        if (fabs(Z0y)<PixelHeight/2) Z0y=0.0; /* Zy = 0 is a special value  */    
        for(iX=0;iX<iXmax;++iX)
         {    /* initial value of orbit Z0 */
           Z0x=ZxMin + iX*PixelWidth;
          }
      }


Normal grid-scan plotting by Robert Munafo[26]

  /* Plot a single pixel, row i and column j

   NOTE:
     itmax is the maximum number of Mandelbrot iterations
     ctr_r and ctr_i are the real and imaginary coordinates of the
       center of the view we want to plot
     min_r is the real coordinate of the left edge of the image
     max_i is the imaginary coordinate of the top of the image
     px_spacing is the width of the image (in real coordinates)
       divided by the number of pixels in a row
     px_radius is half the width of the image (in real coordinates)
  */
  void pixel_53(int i, int j, int itmax)
  {
    double cr, ci;

    ci = max_i - ((double) i) * px_spacing;
    cr = min_r + ((double) j) * px_spacing;
    evaluate_and_plot(cr, ci, itmax, i, j);
  }


Note that grid scan with exponential coordiante mapping is different. Her is example by by Robert Munafo[27]

  /* Plot a single pixel, row i and column j. Use as many rows as you need
     for the image to show the whole Mandelbrot set. */
  void pixel_53(int i, int j, int itmax)
  {
    double cr, ci, o_r, o_i, angle, radius;

    /* compute angle and radius */
    angle = ((double) j) * px_spacing / px_radius * 3.14159265359;
    radius = ((double) i) * px_spacing / px_radius * 3.14159265359;

    /* compute offsets */
    o_r = cos(angle) * px_radius * exp(radius);
    o_i = sin(angle) * px_radius * exp(radius);

    ci = ctr_i + o_i;
    cr = ctr_r + o_r;
    evaluate_and_plot(cr, ci, itmax, i, j);
  }

decomposition[edit | edit source]

Patterns[edit | edit source]

References[edit | edit source]

  1. Euclidean space in wikipedia
  2. Non-Euclidean Geometry by Malin Christersson ( 2018)
  3. viewport in wikipedia
  4. Mightymandel doc
  5. Xaos - view
  6. Claude Heiland-Allen blog
  7. Exponential Map by Robert P. Munafo, 2010 Dec 5. From the Mandelbrot Set Glossary and Encyclopedia, by Robert Munafo, (c) 1987-2020.  
  8. wikipedia : Aspect_ratio_(image)
  9. michael hogg : fractalnet
  10. optimizing zoom animations by Claude Heiland-Allen
  11. wikipedia : Spatial_anti-aliasing
  12. textures-and-sampling from University of Tartu:
  13. "Images of Julia sets that you can trust" by Luiz-Henrique de Figueiredo, Diego Nehab, Jofge Stolfi, Joao Batista Oliveira- IEE 2015
  14. Supersampling in wikipedia
  15. Sub-pixel resolution in wikipedia
  16. wolfram mathematica: AdaptiveSamplingOfSurfaces
  17. Adaptive Sampling, Plotting Math Curve By Xah Lee. Date: 2016-05-01. Last updated: 2016-05-07.
  18. Fractint Drawing Methods
  19. Synchronous-Orbit Algorithm by R Munafo
  20. The Almond BreadHomepage by Michael R. Ganss
  21. Rough Mandelbrot Sets by Neural Outlet.. posted on 23/11/2014
  22. Images of Julia sets that you can trust by Luiz Henrique de Figueiredo, Diego Nehab, Jorge Stolfi, and Joao Batista Oliveira
  23. RIGOROUS BOUNDS FOR POLYNOMIAL JULIA SETS by Luiz Henrique de Figueiredo
  24. Images of Julia sets that you can trust by LUIZ HENRIQUE DE FIGUEIREDO and DIEGO NEHAB
  25. Distance estimation by Claude Heiland-Allen
  26. From the Mandelbrot Set Glossary and Encyclopedia, by Robert Munafo, (c) 1987-2020.Exponential Map by Robert P. Munafo, 2010 Dec 5.
  27. From the Mandelbrot Set Glossary and Encyclopedia, by Robert Munafo, (c) 1987-2020.Exponential Map by Robert P. Munafo, 2010 Dec 5.