Zum Inhalt springen

Datei:Obtaining the inverse function by reflection (small).gif

Aus MOOCsWiki Staging
Originaldatei (224 × 224 Pixel, Dateigröße: 1,01 MB, MIME-Typ: image/gif, Endlosschleife, 388 Bilder, 32 s)
Hinweis: Aufgrund technischer Beschränkungen werden Vorschaubilder hochauflösender GIF-Dateien wie dieser nicht animiert.

Diese Datei stammt aus Wikimedia Commons und kann von anderen Projekten verwendet werden. Die Beschreibung von deren Dateibeschreibungsseite wird unten angezeigt.

Beschreibung

Beschreibung
English: This animation shows how to obtain the inverse function's graph visually, by switching the x and y axis, which is equivalent to reflecting the graph across the diagonal.
Datum
Quelle Eigenes Werk
Urheber Rodrigo Castro Freibott

This is the code used to generate the animations. Play around with it on Shadertoy.

GLSL

# define SIZE 5.
# define THICKNESS 0.05
# define AXTHICKNESS 0.0165
# define MARGIN 0.001

# define STARTCHANGE 2.
# define ENDCHANGE 4.
# define STARTFLIP 5.
# define ENDFLIP 7.

# define PI 3.1415926538

float maxcomp(vec2 p)
{
    return max(p.x, p.y);
}

float rectangle_sdf(vec2 R, vec2 p)
{
    vec2 q = abs(p) - R;
    return length(max(q,vec2(0))) + min(maxcomp(q),0.0);
}

vec2 rotate(vec2 p, float angle)
{
    vec2 q;
    q.x = p.x*cos(angle) - p.y*sin(angle);
    q.y = p.x*sin(angle) + p.y*cos(angle);
    return q;
}

float xletter_sdf(float size, vec2 centre, vec2 p)
{

    vec2 rectangle = vec2(size, size/6.);
    
    p -= centre;
    
    float angle1 = -45.0*PI/180.0;
    vec2 q1 = rotate(p, angle1);
    float arm1 = rectangle_sdf(rectangle, q1);
    
    float angle2 = 45.0*PI/180.0;
    vec2 q2 = rotate(p, angle2);
    float arm2 = rectangle_sdf(rectangle, q2);
    
    return min(arm1, arm2);
}

float yletter_sdf(float size, vec2 centre, vec2 p)
{

    vec2 rectangle1 = vec2(size, size/6.);
    vec2 rectangle2 = vec2(size/3., size/6.);
    
    p -= centre;
    
    // Stand the Y letter upright after flip
    if (iTime > (STARTFLIP + ENDFLIP) / 2.)
    {
        p.x = - p.x;
        p.y = - p.y;
    }
    
    float angle1 = -45.0*PI/180.0;
    vec2 q1 = rotate(p, angle1);
    float arm1 = rectangle_sdf(rectangle1, q1);
    
    float angle2 = 45.0*PI/180.0;
    vec2 q2 = rotate(p, angle2);
    q2 += vec2(size/2., 0.);
    float arm2 = rectangle_sdf(rectangle2, q2);
    
    return min(arm1, arm2);

}

vec2 stretch_diagonally(vec2 p, float stretching_amount)
{

    /** Returns a vector that corresponds to 'p'
     * strecthed (amount>1) or compressed (amount<1) diagonally
     * (closer to, or farther away from, the diagonal)
     * Actually, the behaviour is the opposite,
     * but this is the effect that is seen */

    // Change to base {(1/sqrt(2), -1/sqrt(2)), (1/sqrt(2), 1/sqrt(2))}
    vec2 q;
    q.y = (p.x + p.y) * sqrt(2.)/2.;
    q.x = (p.x - p.y) * sqrt(2.)/2.;
    
    // Stretch along the old base's diagonal, or the new base's horizontal
    q.x *= 1./stretching_amount;
    
    // Change back to original base {(1, 0), (0, 1)}
    vec2 r;
    r.x = q.x/sqrt(2.) + q.y/sqrt(2.);
    r.y = - q.x/sqrt(2.) + q.y/sqrt(2.);
    
    return r;
    
}

void paint(inout vec3 col, in vec3 color, in float activation)
{

    /** Subtracts from 'col' = vec3(1.) (white) a vector
     * so that the color 'color' is given
     * to those pixels with 'activation' == 1 */
    
    col -= vec3(1. - color.r, 1. - color.g, 1. - color.b) * activation;

}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{

    //// ---- Defining pixel's position ---- ////
    
    vec2 p = SIZE * fragCoord.xy / iResolution.xy; // Coordinates from 0 to SIZE
    p -= vec2(SIZE/2., SIZE/2.);  // Origin in center
    p.x *= iResolution.x/iResolution.y; // x coordinate proportional to width
    
    //// ---- Stretching pixel's position along the diagonal ---- ////
    
    // float stretching_amount = sin(iTime);
    float stretching_amount = 2. * (smoothstep(ENDFLIP, STARTFLIP, iTime) - 0.5);
    p = stretch_diagonally(p, stretching_amount);
    
    //// ---- Establishing pixel's color ---- ////
    
    vec3 col = vec3(1.);  // white background
    
    //// Draw function
    
    float func = sin(p.x);  // exp(p.x) OR p.x * p.x OR sin(p.x)
    
    // Function color - transition between red (original function) and blue (its inverse)
    vec3 func_color = vec3(
        smoothstep(STARTCHANGE, ENDCHANGE, iTime), 
        0., 
        smoothstep(ENDCHANGE, STARTCHANGE, iTime)
    );
    
    // Gray for invalid values (e.g. x<0 for sqrt(x), inverse of x^2)
    if (p.x < -PI/2. || p.x > PI/2.) func_color = vec3(0.5);
    
    // Give color if pixel's height is between func - THICKNESS and func + THICKNESS
    paint(
        col,
        func_color,
        smoothstep(func - THICKNESS, func - THICKNESS + MARGIN, p.y)
      * smoothstep(func + THICKNESS + MARGIN, func + THICKNESS, p.y)
    );
         
    //// Draw axes
    
    // x axis - same as FUNCTION, but with func = 0.
    paint(
        col,
        vec3(0.),  // black
        smoothstep(-AXTHICKNESS, -AXTHICKNESS + MARGIN, p.y)
      * smoothstep(AXTHICKNESS + MARGIN, AXTHICKNESS, p.y)
    );
    
    // y axis - same as x axis, but using width instead of height
    paint(
        col,
        vec3(0.),
        smoothstep(-AXTHICKNESS, -AXTHICKNESS + MARGIN, p.x)
      * smoothstep(AXTHICKNESS + MARGIN, AXTHICKNESS, p.x)
    );
    
    //// Draw X and Y labels
    
    // initial positions
    vec2 xpos = vec2(SIZE*0.4, -SIZE*0.075);
    vec2 ypos = vec2(-SIZE*0.075, SIZE*0.4);
    
    // x label
    vec2 px = p - (ypos - xpos)
        * smoothstep(STARTCHANGE, ENDCHANGE, iTime);
    float xd = xletter_sdf(SIZE/17.5, xpos, px);
    paint(
        col,
        vec3(0.),
        smoothstep(xd, xd + MARGIN, 0.)
    );
    
    // y label
    vec2 py = p - (xpos - ypos)
        * smoothstep(STARTCHANGE, ENDCHANGE, iTime);
    float yd = yletter_sdf(SIZE/17.5, ypos, py);
    paint(
        col,
        vec3(0.),
        smoothstep(yd, yd + MARGIN, 0.)
    );
    
    fragColor = vec4(col.rgb, 1.0);
    

}

Lizenz

Ich, der Urheber dieses Werkes, veröffentliche es unter der folgenden Lizenz:
w:de:Creative Commons
Namensnennung Weitergabe unter gleichen Bedingungen
Dieses Werk darf von dir
  • verbreitet werden – vervielfältigt, verbreitet und öffentlich zugänglich gemacht werden
  • neu zusammengestellt werden – abgewandelt und bearbeitet werden
Zu den folgenden Bedingungen:
  • Namensnennung – Du musst angemessene Urheber- und Rechteangaben machen, einen Link zur Lizenz beifügen und angeben, ob Änderungen vorgenommen wurden. Diese Angaben dürfen in jeder angemessenen Art und Weise gemacht werden, allerdings nicht so, dass der Eindruck entsteht, der Lizenzgeber unterstütze gerade dich oder deine Nutzung besonders.
  • Weitergabe unter gleichen Bedingungen – Wenn du das Material wiedermischst, transformierst oder darauf aufbaust, musst du deine Beiträge unter der gleichen oder einer kompatiblen Lizenz wie das Original verbreiten.

Kurzbeschreibungen

Ergänze eine einzeilige Erklärung, was diese Datei darstellt.

In dieser Datei abgebildete Objekte

Motiv

image/gif

1.058.345 Byte

32,3299999999998 Sekunde

224 Pixel

224 Pixel

8400e84eb24ccf5661d3cfc7be31aeb55e1fc0ac

Dateiversionen

Klicke auf einen Zeitpunkt, um diese Version zu laden.

Version vomVorschaubildMaßeBenutzerKommentar
aktuell17:13, 31. Aug. 2022Vorschaubild der Version vom 17:13, 31. Aug. 2022224 × 224 (1,01 MB)wikimediacommons>Rodrigo Castro FreibottUploaded while editing "Inverse function" on en.wikipedia.org

Die folgende Seite verwendet diese Datei:

Metadaten