我在OpenGL程序中绘制了许多二次Bézier曲线.现在,曲线是一个像素的薄和软件生成的,因为我处于一个相当早的阶段,它足以看到什么有效.
很简单,给定3个控制点(P 0到P 2),我在软件中用t从0到1(步长为1/8)来评估下面的等式,并用GL_LINE_STRIP它们将它们链接在一起:
B(t)=(1- t)2 P 0 + 2(1- t)t P 1 + t 2 P 2
B显然,在哪里产生二维向量.
这种方法"足够好",因为即使是我最大的曲线,也不需要超过8步才能看起来弯曲.不过,一条像素细的曲线很难看.
我想编写一个GLSL着色器,它接受控制点和一个统一thickness变量,以使曲线更粗.起初我想过只制作一个像素着色器,它只会thickness / 2在曲线的距离内着色像素,但这样做需要求解三次多项式,并且在着色器内选择三个解决方案看起来不是最好的想法.
然后我试着查看其他人是否已经这样做了.我偶然发现了微软研究院的Loop和Blinn的一份白皮书,其中的人们展示了一种简单的方法来填充曲线下的区域.虽然它在这种程度上运作良好,但我很难适应两条连线曲线之间的绘制.
使用几何着色器查找与单条曲线匹配的边界曲线相当容易.片段着色器会出现问题,应该填满整个事物.他们的方法使用插值纹理坐标来确定片段是否落在曲线之上或之下; 但我想办法用两条曲线来做这件事(我对着色器而言并不是数学专家,所以事实上我并没有弄清楚如何做到这一点当然并不意味着它是不可能的).
我的下一个想法是将填充的曲线分成三角形,并仅在外部部分使用Bézier片段着色器.但是为此我需要将内部曲线和外部曲线分开到可变点,这意味着我必须再次解决方程式,这不是一个真正的选择.
是否有可行的算法用于使用着色器描边二次Bézier曲线?
我有一些地理数据(下面的图像显示了河流的路径为红点),我想用多段三次贝塞尔曲线近似.通过对计算器等问题,在这里和这里我发现由Philip J.施耐德从"图形宝石"的算法.我成功地实现了它并且可以报告即使有数千个点它也非常快.不幸的是,速度带来了一些缺点,即装配非常不合适.请考虑以下图形:

红点是我的原始数据,蓝线是由Schneider算法创建的多段贝塞尔曲线.如您所见,算法的输入是一个容差,至少与绿线表示的一样高.然而,该算法创建了具有太多急转弯的贝塞尔曲线.你也会在图像中看到这些不必要的急转弯.很容易想象,对于所示数据,具有较小急转弯的贝塞尔曲线,同时仍保持最大公差条件(仅将贝塞尔曲线稍微推向品红色箭头的方向).问题似乎是算法从我的原始数据中选取数据点作为各个贝塞尔曲线的终点(品红箭头指示一些嫌疑人).由于贝塞尔曲线的端点受到限制,很明显该算法有时会产生相当尖锐的曲率.
我正在寻找的是一种算法,它使用具有两个约束的多段贝塞尔曲线来近似我的数据:
我发现可以创造更好拟合的解决方案或者仅适用于单个贝塞尔曲线(并且省略了如何在多段贝塞尔曲线中找到每个贝塞尔曲线的良好起点和终点的问题)或者不允许最小曲率约束.我认为最小曲率约束是这里的棘手条件.
这是另一个例子(这是手绘而不是100%精确):

让我们假设图1显示了两者,曲率约束(圆必须适合整个曲线)以及任何数据点与曲线的最大距离(恰好是绿色圆的半径).图2中红色路径的成功近似显示为蓝色.该近似值符合曲率条件(圆可以在整个曲线内滚动并在任何地方触摸它)以及距离条件(以绿色显示).图3显示了路径的不同近似值.虽然它符合距离条件但很明显圆圈不再适合曲率.图4显示了一条不可能用给定约束近似的路径,因为它太尖了.该示例应该说明为了正确地近似路径中的一些尖转弯,算法必须选择不属于路径的控制点.图3显示,如果选择沿路径的控制点,则不能再满足曲率约束.此示例还显示算法必须退出某些输入,因为无法使用给定的约束来近似它.
这个问题是否存在解决方案?解决方案不一定要快.如果需要一天时间来处理1000点,那就没问题了.解决方案也不必是最佳的,因为它必须导致最小二乘拟合.
最后,我将用C和Python实现它,但我也可以阅读大多数其他语言.
我的任务是通过Stage3d(Adobe Flash)技术渲染二次贝塞尔曲线(路径),该技术没有开箱即用的任何扩展(而OpenGl拥有它,据我所知).是的,有一个Starling-Extension-Graphics,但是它使用简单的方法将曲线段划分为许多直线,这为我的长曲线路径生成了很多三角形.
所以..有一种完美的方式来渲染Loop和Blinn的分辨率独立形状.我已经阅读了GPUGems3文章(gpugems3_ch25.html)并将该片段着色器移植到AGAL2:
二次曲线像素着色器
float4 QuadraticPS(float2 p : TEXCOORD0,
float4 color : COLOR0) : COLOR
{
// Gradients
float2 px = ddx(p);
float2 py = ddy(p);
// Chain rule
float fx = (2*p.x)*px.x - px.y;
float fy = (2*p.x)*py.x - py.y;
// Signed distance
float sd = (p.x*p.x - p.y)/sqrt(fx*fx + fy*fy);
// Linear alpha
float alpha = thickness - abs(sd);
if (alpha > 1) // Inside
color.a = 1;
else if (alpha < 0) // Outside
clip(-1);
else
// …Run Code Online (Sandbox Code Playgroud) [序幕]
这个Q&A旨在更清楚地解释我在这里首次发表的近似搜索类的内部工作
我已经被要求提供关于这几次的更多详细信息(由于各种原因)所以我决定写关于这个的Q&A风格主题,我将来可以很容易地参考这个主题并且不需要一遍又一遍地解释它.
[题]
如何逼近Real域(double)中的值/参数以实现多项式,参数函数或求解(困难)方程(如超越)的拟合?
限制
double精确)我需要提高矿井大气散射GLSL片段着色器之一的功能的精度,该着色器可计算单射线与轴对齐的椭球之间的交点。
这是矿山大气散射着色器的核心功能。旧的原始着色器已启用,floats并且可以正常渲染,但是添加缩放后,我发现距离相对较小时会失去精度。在浮子上,地球的可用距离仅为0.005 AU(天文单位)。因此,我尝试将关键功能移植到该端口上,double并且它有所帮助,因此现在可用距离约为1.0 AU(带有较小的伪像)
这是doubleFragment Shader中函数的版本(旧版本的源代码已弃用!!!)
#extension GL_ARB_gpu_shader_fp64 : enable
double abs(double x) { if (x<0.0) x=-x; return x; }
// compute length of ray(p0,dp) to intersection with ellipsoid((0,0,0),r) -> view_depth_l0,1
// where r.x is elipsoid rx^-2, r.y = ry^-2 and r.z=rz^-2
float view_depth_l0=-1.0,view_depth_l1=-1.0;
bool _view_depth(vec3 _p0,vec3 _dp,vec3 _r)
{
double a,b,c,d,l0,l1;
dvec3 p0,dp,r;
p0=dvec3(_p0);
dp=dvec3(_dp);
r =dvec3(_r );
view_depth_l0=-1.0;
view_depth_l1=-1.0;
a=(dp.x*dp.x*r.x)
+(dp.y*dp.y*r.y)
+(dp.z*dp.z*r.z); a*=2.0;
b=(p0.x*dp.x*r.x)
+(p0.y*dp.y*r.y)
+(p0.z*dp.z*r.z); b*=2.0;
c=(p0.x*p0.x*r.x) …Run Code Online (Sandbox Code Playgroud) 我一直试图找到一些地方来帮助我更好地理解DFT以及如何计算它但无济于事.所以我需要帮助理解DFT和它的复数计算.
基本上,我只是在寻找有关如何计算DFT的示例,并解释它是如何计算的,因为最后,我正在寻找创建算法来计算它.