0

Consider the region outside a circle of diameter $a$ and inside the square of side length $b$ where $b>a$. I would like to represent this region using a coordinate system $(u,v)$ where the circle and square are represented by equations of the form $u=constant$. While I appreciate there is no unique way of doing this, I was wondering if there are any particularly natural choices, perhaps based on the mappings between squares and circles contained in https://arxiv.org/ftp/arxiv/papers/1509/1509.06344.pdf.

It appears, however, that those mappings only approach a circle near the centre of the region and I'm not sure how to generalise to my case. Thanks in advance for any help.

Chris
  • 499
  • I'm assuming you want explicit formulas for these, right? Certainly the "simple stretching" idea from the paper is a natural one to implement, but the formula itsel would be a bit tedious. – Eric Nathan Stucky Aug 08 '23 at 17:24
  • Yes, I really do want the formulas. – Chris Aug 08 '23 at 17:39
  • For conformal mapping from square to circle see e.g. https://math.stackexchange.com/questions/1015205/conformal-mapping-circle-onto-square-and-back – R. J. Mathar Aug 10 '23 at 08:32

1 Answers1

1

The region between the circle and the square can be expressed by an angle and a distance from the circle point at that angle to the square point at that angle.

In this image, you can see the resulting shape of the above approach. The $\color{red}{\text{$u$ coordinate is expressed in red}}$, and the $\color{green}{\text{$v$ coordinate is expressed in green}}$. The $u$ coordinate begins at $u=0$, forming a circle, and ends at $u=1$, forming a square.

To achieve the above result starting from cartesian coordinates, first convert the cartesian coordinates to polar coordinates so that you have an angle measurement spanning around the shape and a radius measurement spanning the thickness of the shape. Second, scale the thickness measurement to match the difference in distance between the center of the shapes and their edges at any given angle.

To convert the $(x,y)$ cartesian coordinates to $(r,\theta)$ polar coordinates: $$r=f_1(x,y)=\sqrt{|x^2+y^2|}$$ $$\theta=f_2(x,y)= \begin{cases} \frac{\pi}{2}-\arctan(\frac{x}{y}), & \text{if $y>=0$} \\ \frac{3\pi}{2}-\arctan(\frac{x}{y}), & \text{if $y>0$} \end{cases}$$

To convert the $(r,\theta)$ polar coordinates to $(u,v)$ region coordinates in the space between the circle of diameter $a$ and square of side length $b$: $$u=f_3(r,\theta)= \begin{cases} (r-\frac{a}{2})(b\sqrt{|1+(\tan\theta)^2|}-\frac{a}{2}), & \text{if $|\cos\theta|>=|\sin\theta|$ or more simply $|x|>=|y|$ if $x$ and $y$ are handy} \\ (r-\frac{a}{2})(b\sqrt{|1+(\frac{1}{\tan\theta})^2|}-\frac{a}{2}), & \text{if $|\cos\theta|<|\sin\theta|$ or more simply $|x|<|y|$ if $x$ and $y$ are handy} \end{cases}$$ $$v=f_4(\theta)=\frac{\theta}{2\pi}$$

The conversion above can be simplified by substituting $c$ for the $\theta$ expressions: $$c=g_3(\theta)= \begin{cases} \tan\theta, & \text{if $|\cos\theta|>=|\sin\theta|$ or more simply $|x|>=|y|$ if $x$ and $y$ are handy} \\ \frac{1}{\tan\theta}, & \text{if $|\cos\theta|<|\sin\theta|$ or more simply $|x|<|y|$ if $x$ and $y$ are handy} \end{cases}$$ $$u=g_4(r,c)=(r-\frac{a}{2})(b\sqrt{|1+c^2|}-\frac{a}{2})$$ $$v=g_5(\theta)=\frac{\theta}{2\pi}$$

You can see the equation in action with this shader here:

#version 300 es

precision highp float; precision highp sampler2D;

// normalized coordinates, (0,0) is the bottom left in vec2 uv; // resulting fragment color, you may name it whatever you like out vec4 out_color;

// size of the canvas in pixels uniform vec2 u_resolution; // elapsed time since shader compile in seconds uniform float u_time; // mouse pixel coordinates are in canvas space, (0,0) is top left uniform vec4 u_mouse; // texture array uniform sampler2D u_textures[16];

const float pi = 3.14159265; const float pi2 = pi * 2.0;

// Converts cartesian to radians in range [0, pi2] float atan2positive(vec2 v) { // Shift range to [pi, 0] repeated across x axis float a = atan(v.x / v.y) + pi / 2.0; // Flip regions and shift lower region past upper to final single region return v.y >= 0.0 ? pi - a : pi2 - a; }

// Converts cartesian unit square to polar unit circle vec2 cartesianToNormalizedPolar(vec2 cartesian) { return vec2(atan2positive(cartesian)/pi2, length(cartesian)); }

void main(){ // Find bounding aspect float minResolution = min(u_resolution.x, u_resolution.y); // Find the normalized margin size vec2 centeringShift = (u_resolution - minResolution) / minResolution; // Cartesian coordinates in ranges <x[-1, 1], y[-1, 1]> vec2 cartesian = 2.0 * uv * u_resolution / minResolution - 1.0 - centeringShift; // Polar coordinates in ranges <angle[0, 1], radius[0, 1]> vec2 polar = cartesianToNormalizedPolar(cartesian);

// Radius of the circle to act as the zero coordinate
float a = 0.0;
// Length of one side of the square to act as the one coordinate
float b = 1.0;

// Distance to the square when on the left or right side
float sx = length(vec2(b, b * sin(polar.x*pi2)));
// Distance to the square when on the top or bottom side
float sy = length(vec2(b * cos(polar.x*pi2), b));
// Distance to the square when on any side
float s = abs(cartesian.x) &gt;= abs(cartesian.y) ? sx : sy;
// Ratio of the distance from the circle to the square the pixel has traveled
float d = (polar.y - a) / (s - a);
// Inscription coordinates in the region between the circle and square
vec2 inscription = vec2(polar.x, pow(d, 15.0));

out_color = vec4(inscription, 0, 1);

}