所以我是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
}
答案 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个向量之间的夹角余弦乘以两个向量的大小(长度)。
dot( A, B ) == | A | * | B | * cos( alpha )
V
和D
的点积等于直线(O
,D
)和向量V = P - O
之间的夹角余弦,乘以V
的数量(长度),因为D
是unit vector(D
的长度是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);
}