距线的距离-Shadertoy

时间:2018-10-14 17:58:42

标签: glsl shader

所以我是shadertoy的新手,我一直在玩一些东西,但是我不知道的一件事是如何计算点到直线的距离。我自己可以用铅笔和纸轻松地完成此操作,但是当我实际上尝试将其应用于sharttoy时,总是会弄乱某些内容。这是我所拥有的:

    public bool Verify()
    {
        if(AuthenticationType == EAuthenticationType.Unspecified)
        {
            if(CodeLength > 0)
                return AuthenticationCode.Length == CodeLength;
            return true;
        }

        var strRegex = new StringBuilder("^[");
        if((AuthenticationType & EAuthenticationType.Numeric) != 0)
            strRegex.Append(@"\d");
        if((AuthenticationType & EAuthenticationType.Alpha) != 0)
            strRegex.Append("a-zA-Z");
        if((AuthenticationType & EAuthenticationType.Symbols) != 0)
            strRegex.Append("!\\\"£$%^&*\\(\\)\\[\\]\\{\\}@'~#\\\\/,\\.\\<\\>?\\-=_+¬|;:");

        strRegex.Append("]");
        if(CodeLength > 0)
            strRegex.Append($"{{{CodeLength}}}$");
        else
            strRegex.Append("+$");

        // Original code
        return Regex.IsMatch(strRegex.ToString(), AuthenticationCode);

        //Workaround
        var match = Regex.Match(strRegex.ToString(), AuthenticationCode);
        return match.Captures[0].Value == AuthenticationCode;
    }

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

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
}

2 个答案:

答案 0 :(得分:1)

@兔子

谢谢,但是代码在对 dfLine() 的调用中缺少 P,所以它可能是 https://www.shadertoy.com/view/3tyyDR :

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 = 2.1; //slope
 float lb = 0.5; //intercept    
 vec2 P = vec2(uv.x, uv.y); //Current scanned point
 float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  P);    
 //vec3  color  = dist * vec3(1.0);  //gradient
 float onLine = step(dist, 0.01);   // 
 vec3  color  = onLine * vec3(1.0); 
 fragColor = vec4(color, 1.0);    
}

或者像一个简单的动画和流畅的线条:

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 = sin(iTime); // animated slope, 1.1
 float lb = mix(0.5, 1.0, sin(iTime)); //0.5; //intercept   0.5-1.0 to keep it in the view port 
 vec2 P = vec2(uv.x, uv.y);
 //float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  vec2(uv.x,uv.y));

 float dist = dfLine(vec2(0.0, lb), vec2(1.0, lm),  P);
 float onLine = 1.0 - smoothstep(0.0, 0.02, dist);

 vec3  color  = onLine * vec3(1.0);
 fragColor = vec4(color, 1.0);   
}

答案 1 :(得分:0)

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

X = O + D * dot(P-O, D);

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

enter image description here

dot( A, B ) == | A | * | B | * cos( alpha ) 

VD的点积等于直线(OD)和向量V = P - O之间的夹角余弦,乘以V的数量(长度),因为Dunit vectorD的长度是1.0),

在您的情况下,该行由Linear equation给出,格式为:

f(x) = lb + lmp * x;

线上的点是( 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));

    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);
}