Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 精确亚像素线绘制算法(光栅化算法)_Algorithm_Math_Graphics_Raytracing_Bresenham - Fatal编程技术网

Algorithm 精确亚像素线绘制算法(光栅化算法)

Algorithm 精确亚像素线绘制算法(光栅化算法),algorithm,math,graphics,raytracing,bresenham,Algorithm,Math,Graphics,Raytracing,Bresenham,我需要一个算法,它可以(有点)慢,但必须要更准确。我的意思是:每一个触摸到的像素都应该被打印出来。不多也不少!这意味着使用更粗的线或类似的线不是一个选项,因为将涉及太多的像素。另外,我不需要一个图形框架或类似的东西,我需要的是算法!应用程序不是真正的“图形”,而是在像素是“瓷砖”的地方 对我来说,主要的问题是我需要亚像素精度,这意味着一条线可以从0.75/0.33开始,而不仅仅是像整数值一样从0/0开始。在过去的几个小时里,我试图创建一个有效的解决方案,但无法使其有效-边缘案例太多了 首先,我认

我需要一个算法,它可以(有点)慢,但必须要更准确。我的意思是:每一个触摸到的像素都应该被打印出来。不多也不少!这意味着使用更粗的线或类似的线不是一个选项,因为将涉及太多的像素。另外,我不需要一个图形框架或类似的东西,我需要的是算法!应用程序不是真正的“图形”,而是在像素是“瓷砖”的地方

对我来说,主要的问题是我需要亚像素精度,这意味着一条线可以从0.75/0.33开始,而不仅仅是像整数值一样从0/0开始。在过去的几个小时里,我试图创建一个有效的解决方案,但无法使其有效-边缘案例太多了

首先,我认为像中的算法这样的抗锯齿版本应该可以实现,但它打印的像素太多(特别是对于起点和终点),在某些情况下,它仍然会丢失一些像素,例如非常短的线

然后我试着让布雷森汉姆工作,正如我指出的那样,我用“else if”替换了第二个“if”,它更接近,但仍然不存在。然后我尝试将Bresenham从整数精度移动到浮点精度,这导致了一个无休止的循环(因为x,y值跳过了finish条件
if(y1==y2&&x1==x2)

我可以使用解决方案,但我应该使用哪个
delta
?例如,如果我使用0.1,我仍然会丢失一些像素,使用较小的值可能会花费太长时间(并且仍然丢失像素)

C/Java/中的工作解决方案。。。将不胜感激。至少对于Octant1它应该是有效的,但是一个完整的解决方案会更好


更新:我想到了以下想法:使用朴素的线光栅化,您可以为每个点计算4个候选像素。然后检查这4个像素,如果这条线真的穿过它们。但我不确定线条/方框相交是否足够快。

如果线条很细且像素为矩形(正方形):

然后考虑使用体素网格遍历算法,例如,参见WOO和AMANATDES的文章“< /P>”。 (在网格遍历部分)

对评论的答复:
X坐标变量的正确初始化(Y相同)


我的答案中的示例

如果您只需要恒定的颜色(不需要按像素的使用面积插值),则使用DDA

void line\u DDA\u子像素(int x0,int y0,int x1,int y1,int col)//DDA子像素->厚
{
int kx,ky,c,i,xx,yy,dx,dy;
x1-=x0;kx=0;如果(x1>0)kx=+1;如果(x10)ky=+1;如果(y1=y1)

对于(c=x1,i=0;i“应打印每个接触的像素”,即使0.01像素或更少像素与线条相交?线条两端的形状是什么(圆形、凹面、凸面、平面)?是的,如果存在数学相交,则应将其包括在内(当然,我们可以假设常见的舍入误差)。线条末端应为平面(没有绒毛或抗锯齿,只是“数学”结尾)颜色呢?线条颜色是常量还是应该像抗锯齿一样根据像素的使用面积进行插值?颜色不是必需的。这确实是MBo在回答中指出的同一问题(实际实现):空间细分,所以我只需要知道“光线”是否击中一个像素。嗯,我看我的答案可能比那个更适合这个问题。我相信我的解决方案正是这个问题所要求的。谢谢!这看起来不错-我会调查!我的像素是矩形的,但不是二次的,所以我认为这可以工作。你的图中显示起点或终点只能位于中心-也可以是任意起点或终点吗?从包含任意起点位置的磁贴开始,到包含任意终点位置的磁贴结束。遍历沿着起点和终点相交的线进行。因此,是的,是一个arbit很少有开始和结束的可能。是的,任意位置都是可能的。谢谢,看起来不错。我在这里实现了它:虽然我用python实现了java代码(github链接)以进行原型设计,但在接下来的几天里,我会为其他想法提供答案。而且它并不适用于所有情况(起点和终点的所有组合)。我的单元格以整数为中心,我的起点和终点是任意浮点值。我更改了以下内容,它成功了:
如果stepX<0:maxX=deltaX*(0.5+(tmp-np.round(tmp));否则:maxX=deltaX*(0.5-(tmp-np.round(tmp)))
与使用stepY的maxY相同。添加了
作为代码中的行尾符号如果需要面积百分比,那么它可以从变量c的状态中导出,但我使用了它,因为我不需要它。这是一个很好的特定情况算法,适用于OP所寻找的,但AFAICT这并不能解决极有可能出现的情况线的起点和终点坐标是非整数值。如果我用double(例如double)替换int参数,它会起作用吗?@Karussell是的,但是以经典方式生成dy/dx或dx/dy会更快。此外,还应该通过if((x-floor(x))>0.0)添加子像素点…同样的道理也适用于y@Karussell我会把它保留在整数上,如果需要的话,在每个端点上加上这2个子点。
  DX = X2 - X1
  tDeltaX = GridCellWidth / DX
  tMaxX = tDeltaX * (1.0 - Frac(X1 / GridCellWidth)) 
  //Frac if fractional part of float, for example, Frac(1.3) = 0.3
void pnt(int x,int y,int col);