Thursday, December 31, 2015

Escher's "Square Limit" as a circle


M.C. Escher created the square limit woodcut in 1964.

input: Escher's "Square Limit" woodcut


Schwarz-Christoffel mapping

elliptical grid mapping

FG-squircular mapping

Shirley-Chiu concentric map






Coxeter {6,4} tiling of the Poincare disk

H.S.M. Coxeter published a checkered {6,4} hyperbolic tiling of the Poincare disk in his 1957 paper: "Crystal Symmetry and Its Generalizations".

Here, we convert the conformal hyperbolic disk to hyperbolic squares.

input: Coxeter {6,4} tiling of Poincare disk


Schwarz-Christoffel mapping

elliptical grid mapping


FG-squircular mapping

Shirley-Chiu concentric map



Saturday, September 19, 2015

Square O'Clock


input file: Roman numeral clock

Schwarz-Christoffel mapping

elliptical grid mapping


FG-squircular mapping


Shirley-Chiu concentric map





Monday, September 14, 2015

Andy Warhol's Campbell soup


circularized pop art. Mmm mmm good.


input: Andy Warhol's soup cans

Schwarz-Christoffel mapping

FG-squircular mapping

elliptical grid mapping



Shirley-Chiu concentric map







Friday, September 11, 2015

Circular Monopoly


Monopoly is a board game traditionally played on a square board. What happens if we convert the board to a circle?

input: Monopoly board game


Schwarz-Christoffel mapping


FG-squircular mapping
elliptical grid mapping



Shirley-Chiu concentric map





Thursday, September 10, 2015

2015 NBA champions

Here is a circular logo of the Golden State Warriors converted into a square.

input file: Golden State Warriors


Schwarz-Christoffel mapping



FG-squircular mapping

elliptical grid mapping




Shirley-Chiu concentric map





Circular Brady Bunch


Here are results of different square-to-circle mapping algorithms on a bunch of television icons of the 70's. Marcia. Marcia. Marcia!


input file: Brady Bunch


Schwarz-Christoffel conformal mapping
elliptical grid mapping
FG-squircular mapping
Shirley-Chiu concentric map



Not to be confused with this "The Brady Bunch Movie" refrigerator magnet I found on ebay!



Wednesday, September 9, 2015

Schwarz-Christoffel mapping


This conformal mapping developed in the 1860s by Hermann Schwarz and Elwin Christoffel can be used to map a circle to a square and vice versa.






















The equations for mapping the circular disc to a square region (and vice versa) are:

where z and w are points in the complex plane defined as

z = x + y i
w = u + v i

and

F is the Legendre elliptic integral of the 1st kind.
cn is a Jacobi elliptic function.
Ke is the complete elliptic integral of the 1st kind with parameter m = ½
(x,y) are coordinates on the square
(u,v) are coordinates on the circular disc


See Section 7 of my paper (page 19) for an explanation of the formulas
http://arxiv.org/ftp/arxiv/papers/1509/1509.06344.pdf


========================================================

Here is an example image of using the Schwarz-Christoffel mapping on a square chessboard

Schwarz-Christoffel chessboard













and another on MC Escher's "Circle Limit IV"; i.e. angels and devils inside the Poincare disk.

Schwarz-Christoffel for squared Circle Limit IV














Note that the Jacobi cn() function is an even function, so cn(x,k) = cn(-x,k).

Saturday, September 5, 2015

FG-Squircular Mapping


The elliptical grid mapping is by no means the only way to map the square to a circle and vice versa.
In this entry, I shall introduce a disc to square mapping based on the Fernandez-Guasti squircle.
























Here are the equations for the mapping.

square to circle:
u = x √(x² + y² - x²y²) / √(x² + y²)
v = y √(x² + y² - x²y²) / √(x² + y²)

circle to square:
x = √½  sgn(uv)/v √(u² + v² - √(u² + v²) √(u² + v² - 4u²v²) )
y = √½  sgn(uv)/u √(u² + v² - √(u² + v²) √(u² + v² - 4u²v²) )


where sgn(z) is the signum function;
(u,v) are circular coordinates in the domain {(u,v) | u² + v² ≤ 1}
(x,y) are square coordinates in the range [-1,1] x [-1,1]

Note: We need to handle zero inputs as a special case.
When input u or v is zero, just set x = u and y = v.
When input x or y is zero, just set u = x and v = y.

The main idea behind this mapping is to map concentric circles inside the circular disc to Fernandez-Guasti squircles inside the square.

See http://squircular.blogspot.com/2015/09/fernandez-guastis-squircle.html for more details on the Fernandez-Guasti squircle.

C++ sample implementation below
--------------------------------------------------------------------------------------------------

// sample code accompanying the paper:
// "Analytical Methods for Squaring the Disc"
// http://arxiv.org/abs/1509.06344

#include <stdio.h>
#include <math.h>

#define epsilon 0.0000001

inline double sgn(double input)
{
    double output = 1.0;
    if (input < 0.0) {
        output = -1.0;
    }
    return output;
}


// FG-Squircular mapping
// mapping a circular disc to a square region
// input: (u,v) coordinates in the circle
// output: (x,y) coordinates in the square
void fgsDiscToSquare(double u, double v, double& x, double& y)
{
    if ( (fabs(u) < epsilon) || (fabs(v) < epsilon))  {
        x = u;
        y = v;
        return;
    }

    double u2 = u * u;
    double v2 = v * v;
    double r2 = u2 + v2;
    double uv = u * v;
    double fouru2v2 = 4.0 * uv * uv;
    double rad = r2 * (r2 - fouru2v2);
    double sgnuv = sgn(uv);
    double sqrto = sqrt(0.5 * (r2 - sqrt(rad)));

    x = sgnuv/v * sqrto;
    y = sgnuv/u * sqrto;

}


// FG-Squircular mapping
// mapping a square region to a circular disc
// input: (x,y) coordinates in the square
// output: (u,v) coordinates in the circle
void fgsSquareToDisc(double x, double y, double& u, double& v)
{
    if ( (fabs(x) < epsilon) || (fabs(y) < epsilon))  {
        u = x;
        v = y;
        return;
    }
 
    double x2 = x * x;
    double y2 = y * y;
    double r2 = x2 + y2;
    double rad = sqrt( r2 - x2 * y2);

    // This code is amenable to the fast reciprocal sqrt floating point trick
    // https://en.wikipedia.org/wiki/Fast_inverse_square_root
    double reciprocalSqrt =  1.0/sqrt(r2);
 
    u = x * rad * reciprocalSqrt;
    v = y * rad * reciprocalSqrt;
}


int main()
{
    double x,y;
    double u,v;

    fgsSquareToDisc(0.0,-0.789,u,v);
    fgsDiscToSquare(u,v,x,y);
 
    printf("%f %f\n",u,v);
    printf("%f %f\n",x,y);

    fgsDiscToSquare(-0.31415, -0.926535,x,y);
    fgsSquareToDisc(x,y,u,v);
 
    printf("%f %f\n",x,y);
    printf("%f %f\n",u,v);

    return 0;
}

Thursday, September 3, 2015

Fernandez-Guasti's squircle


In 1992, Manuel Fernandez-Guasti introduced a smooth algebraic curve that lies between the circle and the square.

The curve has two parameters: radius r and squareness s


















This is a quartic curve (i.e. degree 4) because of the x²y² term.

When s = 0, the FG-squircle is a circle with radius r.
When s = 1, the FG-squircle is a square with side length 2r.

In between, it is a shape that resembles both the circle and the square


Note: For this discussion, we shall limit the scope of the curve to
-r ≤ x ≤ r and -r ≤ y ≤ r

This quartic polynomial equation can have values for (x,y) outside this scope, but we will ignore those regions.

See http://148.206.32.135/mfg/arti/90-94/agrec-ijmest92.pdf
for Fernandez-Guasti's original paper.

Squared Corporate Logos


The following logos are circular ones mapped to a square.





















Thanks to Seb Przd for inspiring this post

Mapping a Circle to a Square

Philip Nowell (http://mathproofs.blogspot.com/2005/07/mapping-square-to-circle.html)
has an equation for mapping a square to a circle.

For this blog entry, I use a slightly different notation from his equations; i.e.
u = x'
v = y'


(u,v) are circular coordinates in the domain {(u,v) | u² + v² ≤ 1}
(x,y) are square coordinates in the range [-1,1] x [-1,1]

Many people have asked for the inverse of the mapping. I provide it below:


x = ½ √( 2 + 2u√2 + u² - v² ) - ½ √( 2 - 2u√2 + u² - v² )
y = ½ √( 2 + 2v√2 - u² + v² ) - ½ √( 2 - 2v√2 - u² + v² )

or more legibly



The forward equations for the mapping are:


u = x √( 1 - ½ y² )
v = y √( 1 - ½ x² )

Here are some examples of the forward & inverse mappings at work.






For a proof/derivation of the inverse equations, see my paper in
arxiv: "Analytical Methods for Squaring the Disc"


In this blog, I shall refer to this mapping as the elliptical grid mapping.  I chose this name because the mapping has a predilection to map a rectilinear grid into a grid of elliptical arcs in the circle.  See Nowell's blog for a discussion and derivation of the elliptical arcs.

Here are more examples of the mapping:

Starbucks logo converted to a square
Andy Warhol's pop art "Marilyn" as a circle

[ C++ implementation source code below]
------------------------------------------------------------------------------------------


// sample code accompanying the paper:
// "Analytical Methods for Squaring the Disc"
// http://arxiv.org/abs/1509.06344

#include <stdio.h>
#include <math.h>

// Elliptical Grid mapping
// mapping a circular disc to a square region
// input: (u,v) coordinates in the circle
// output: (x,y) coordinates in the square
void ellipticalDiscToSquare(double u, double v, double& x, double& y)
{
    double u2 = u * u;
    double v2 = v * v;
    double twosqrt2 = 2.0 * sqrt(2.0);
    double subtermx = 2.0 + u2 - v2;
    double subtermy = 2.0 - u2 + v2;
    double termx1 = subtermx + u * twosqrt2;
    double termx2 = subtermx - u * twosqrt2;
    double termy1 = subtermy + v * twosqrt2;
    double termy2 = subtermy - v * twosqrt2;
    x = 0.5 * sqrt(termx1) - 0.5 * sqrt(termx2);
    y = 0.5 * sqrt(termy1) - 0.5 * sqrt(termy2);
    
}


// Elliptical Grid mapping
// mapping a square region to a circular disc
// input: (x,y) coordinates in the square
// output: (u,v) coordinates in the circle
void ellipticalSquareToDisc(double x, double y, double& u, double& v)
{
    u = x * sqrt(1.0 - y*y/2.0);
    v = y * sqrt(1.0 - x*x/2.0);    
}


int main()
{
    double x,y;
    double u,v;

    ellipticalSquareToDisc(-0.789,0.654,u,v);
    ellipticalDiscToSquare(u,v,x,y);
    
    printf("%f %f\n",u,v);
    printf("%f %f\n",x,y);

    ellipticalDiscToSquare(0.31415, -0.926535,x,y);
    ellipticalSquareToDisc(x,y,u,v);
    
    printf("%f %f\n",x,y);
    printf("%f %f\n",u,v);

    return 0;
}