计算点和矩形之间的有符号距离
Calculate signed distance between point and rectangle
我正在尝试用 GLSL 编写一个函数,returns 到矩形的有符号距离。矩形是轴对齐的。我觉得有点卡住了;我只是想不通我需要做什么才能让它发挥作用。
我想到的最好的是:
float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
// signed distances for x and y. these work fine.
float dx = max(tl.x - uv.x, uv.x - br.x);
float dy = max(tl.y - uv.y, uv.y - br.y);
dx = max(0.,dx);
dy = max(0.,dy);
return sqrt(dx*dx+dy*dy);
}
生成的矩形如下所示:
线条显示与矩形的距离。它工作正常,但仅适用于矩形外的距离。在矩形内部,距离是静态的 0.
.
如何使用统一公式获得矩形内的准确距离?
这个怎么样...
float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
vec2 d = max(tl-uv, uv-br);
return length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y));
}
这是 result,其中绿色表示正距离,红色表示负距离(代码如下):
细分:
获取到 x 和 y 边界的有符号距离。 u - left
和 right - u
是两个 x 轴距离。取这些值的最大值给出到最近边界的有符号距离。查看 d.x
和 d.y
分别显示在下图中。
合并 x 和 y:
如果两个值都是负数,取最大值(即最接近边界)。这是通过 min(0.0, max(d.x, d.y))
.
完成的
如果只有一个值是正数,那就是我们想要的距离
如果两个值都是正数,则最近的点是一个角,在这种情况下我们需要长度。这可以通过获取长度并确保两个值都是正数来与上述情况结合:length(max(vec2(0.0), d))
.
等式的这两部分是互斥的,即只有一个会产生非零值,并且可以相加。
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
uv -= 0.5;
uv *= vec2(iResolution.x/iResolution.y,1.0);
uv += 0.5;
float d = sdAxisAlignedRect(uv, vec2(0.3), vec2(0.7));
float m = 1.0 - abs(d)/0.1;
float s = sin(d*400.0) * 0.5 + 0.5;
fragColor = vec4(s*m*(-sign(d)*0.5+0.5),s*m*(sign(d)*0.5+0.5),0,1);
}
我正在尝试用 GLSL 编写一个函数,returns 到矩形的有符号距离。矩形是轴对齐的。我觉得有点卡住了;我只是想不通我需要做什么才能让它发挥作用。
我想到的最好的是:
float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
// signed distances for x and y. these work fine.
float dx = max(tl.x - uv.x, uv.x - br.x);
float dy = max(tl.y - uv.y, uv.y - br.y);
dx = max(0.,dx);
dy = max(0.,dy);
return sqrt(dx*dx+dy*dy);
}
生成的矩形如下所示:
线条显示与矩形的距离。它工作正常,但仅适用于矩形外的距离。在矩形内部,距离是静态的 0.
.
如何使用统一公式获得矩形内的准确距离?
这个怎么样...
float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
vec2 d = max(tl-uv, uv-br);
return length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y));
}
这是 result,其中绿色表示正距离,红色表示负距离(代码如下):
细分:
获取到 x 和 y 边界的有符号距离。
u - left
和right - u
是两个 x 轴距离。取这些值的最大值给出到最近边界的有符号距离。查看d.x
和d.y
分别显示在下图中。合并 x 和 y:
如果两个值都是负数,取最大值(即最接近边界)。这是通过
min(0.0, max(d.x, d.y))
. 完成的
如果只有一个值是正数,那就是我们想要的距离
如果两个值都是正数,则最近的点是一个角,在这种情况下我们需要长度。这可以通过获取长度并确保两个值都是正数来与上述情况结合:
length(max(vec2(0.0), d))
.
等式的这两部分是互斥的,即只有一个会产生非零值,并且可以相加。
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
uv -= 0.5;
uv *= vec2(iResolution.x/iResolution.y,1.0);
uv += 0.5;
float d = sdAxisAlignedRect(uv, vec2(0.3), vec2(0.7));
float m = 1.0 - abs(d)/0.1;
float s = sin(d*400.0) * 0.5 + 0.5;
fragColor = vec4(s*m*(-sign(d)*0.5+0.5),s*m*(sign(d)*0.5+0.5),0,1);
}