与直线的距离——Shadertoy

1 shader glsl

所以我是shadertoy的新手,我一直在玩一些东西,但我不明白的一件事是如何计算点到线的距离。我可以轻松地用铅笔和纸自己完成,但当我实际尝试将其应用于 Shadertoy 时,不知怎的,我总是搞砸一些东西。这是我所拥有的:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    uv.x -= 0.5; //Puts the origin at the center of the screen

    float r; //Red value
    float g; //Green value
    float b; //Blue value

    float lm = 1.1; //slope
    float lb = 0.5; //intercept

    //Slope/intercept declarations manipulate line
    //second line
    float lmp = 0.0-(1.0/lm); //calculates the slope of the perpendicular line
    float lbp = lb + uv.y + lmp*(uv.x); //and the intercept

    //Intersection
    float ix = (lbp-lb)/(lm-lmp); //Intersection Y
    float iy = lm*(ix)+lb; //Intersection X based off of the first equation
    //distance
    float dist = sqrt(pow((uv.x - ix),2.0)+pow((uv.y - iy),2.0));

    if (dist < 0.05){

        r = 1.0;
        g = 1.0;
        b = 1.0;
    }

    fragColor = vec4(r,g,b,1.0); //supposed to draw a line
}
Run Code Online (Sandbox Code Playgroud)

现在,这是来自 Flyguy 的“Neontoy”项目的一些东西,它不仅有效,而且比我的短得多。

float dfLine(vec2 start, vec2 end, vec2 uv)
{
    start *= scale;
    end *= scale;

    vec2 line = end - start;
    float frac = dot(uv - start,line) / dot(line,line);
    return distance(start + line * clamp(frac, 0.0, 1.0), uv);
}
Run Code Online (Sandbox Code Playgroud)

Rab*_*d76 6

如果有一条由点 ( O) 和方向 ( D) 给出的线,则该线上距离点 p 最近的点可以计算如下

X = O + D * dot(P-O, D);
Run Code Online (Sandbox Code Playgroud)

2 个向量的点积等于 2 个向量之间的角度的余弦乘以两个向量的大小(长度)。

在此输入图像描述

dot( A, B ) == | A | * | B | * cos( alpha ) 
Run Code Online (Sandbox Code Playgroud)

V和的点积D等于直线 ( O, D) 和向量 之间的角度的余弦V = P - O乘以 的量(长度)V,因为D单位向量( 的长度D为 1.0),

在您的情况下,该线由以下形式的线性方程给出:

f(x) = lb + lmp * x;
Run Code Online (Sandbox Code Playgroud)

直线上的点为 ( 0.0 , lb) ,方向为 ( 1.0 , lmp) 。

将其应用到代码中会产生以下片段着色器:

float dfLine(vec2 O, vec2 dir, vec2 P)
{
    vec2 D = normalize(dir);
    vec2 X = O + D * dot(P-O, D);

    return distance(P, X);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;
    uv.x -= 0.5; //Puts the origin at the center of the screen

    float lm = 1.1; //slope
    float lb = 0.5; //intercept

    float dist = dfLine(vec2(0.0, lb), vec2(1.0, lmp), uv);

    float onLine = step(dist, 0.05);   // 1.0 if on line, else 0.0
    vec3  color  = onLine * vec3(1.0); 

    fragColor = vec4(color, 1.0);
}
Run Code Online (Sandbox Code Playgroud)