C# 从Bresenham算法中获得唯一的结果

C# 从Bresenham算法中获得唯一的结果,c#,math,computational-geometry,C#,Math,Computational Geometry,我想用光栅化一条线。我的插值顶点不应包含对角线步长。我在StackOverflow上做了一些搜索,看起来差不多就是我需要的东西 我唯一的问题是,如果我改变输入顺序,我需要得到相同的结果,我的意思是,如果我交换线的起始点和端点,我需要得到相同的插值顶点集 //the Method definition List<Point> plotPoints(Point startPoint, Point endPoint); //The thing I'm looking for plotPo

我想用光栅化一条线。我的插值顶点不应包含对角线步长。我在StackOverflow上做了一些搜索,看起来差不多就是我需要的东西

我唯一的问题是,如果我改变输入顺序,我需要得到相同的结果,我的意思是,如果我交换线的起始点端点,我需要得到相同的插值顶点集

//the Method definition
List<Point> plotPoints(Point startPoint, Point endPoint);

//The thing I'm looking for
plotPoints(startPoint, endPoint)==plotPoints(endPoint, startPoint)
//方法定义
列出绘图点(点起点、点终点);
//我要找的东西
绘图点(起点,终点)=绘图点(终点,起点)
代码几乎与相同。不过,我做了一些定制,以满足我的需求:

        private float step=0.5;
        public static List<Vector3> plotPoints(float x0, float y0, float x1, float y1) {
            List<Vector3> plottedPoints = new List<Vector3>();
            float dx = Mathf.Abs(x1 - x0), sx = x0 < x1 ? step : -step;
            float dy = -Mathf.Abs(y1 - y0), sy = y0 < y1 ? step: -step;
            float err = dx + dy, e2; /* error value e_xy */

            for (; ; ) {  /* loop */
                if (x0 == x1 && y0 == y1) break;
                plottedPoints.Add(new Vector3(x0,0, y0));
                e2 = 2 * err;
                if (e2 >= dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */
                else if (e2 <= dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */
            }

            return plottedPoints;
        }
private float step=0.5;
公共静态列表打印点(浮点x0、浮点y0、浮点x1、浮点y1){
List plottedPoints=新列表();
浮点数dx=Mathf.Abs(x1-x0),sx=x0=dy){err+=dy;x0+=sx;}/*e_xy+e_x>0*/

否则,如果(e2如注释中所述,一个技巧是规范化输入,以便如果交换端点,它们将自动交换回


一种可能的方法是强制端点按字典顺序排列(首先是最小的X,如果是平局,则是最小的Y)。

如注释中所述,一个技巧是规范化输入,以便如果交换端点,它们将自动交换回


一种可能的方法是强制端点按字典顺序排列(首先是最小的X,如果是平局,则是最小的Y)。

DDA算法没有这样的问题,它可以明确表示为

X = X0 + (k.DX) rnd D
Y = Y0 + (k.DY) rnd D
其中
D=max(|DX |,| DY |)
rnd
是一个舍入操作,
k
0
D

如果交换端点,则增量将改变符号,然后进行交易

Y0+(k.DY)rnd

为了

Y1+((D-k)。(-DY))rnd=Y1-DY+(k.DY)rnd=Y0+(k.DY)rnd

这意味着算法自然是“可逆的”



要实现这一点,
rnd
操作必须具有平移不变性属性,
rnd(x+n)=rnd(x)+n
,它对应于
(k.DY)rnd=floor((k.DY+S)/D)
,其中
S
是一些舍入偏移(通常
0
D>>1
).

DDA算法不存在这样的问题,可以明确表示为

X = X0 + (k.DX) rnd D
Y = Y0 + (k.DY) rnd D
其中
D=max(|DX |,| DY |)
rnd
是一个舍入操作,
k
0
D

如果交换端点,则增量将改变符号,然后进行交易

Y0+(k.DY)rnd

为了

Y1+((D-k)。(-DY))rnd=Y1-DY+(k.DY)rnd=Y0+(k.DY)rnd

这意味着算法自然是“可逆的”



要实现这一点,
rnd
操作必须具有平移不变性属性,
rnd(x+n)=rnd(x)+n
,它对应于
(k.DY)rnd=floor((k.DY+S)/D)
,其中
S
是一些舍入偏移(通常
0
D>>1
).

你在哪里卡住了?你能显示一些代码吗?我添加了这个方法。如果我交换起点和终点,我需要得到相同的结果。链接主题的
ants280
方法是否产生相同的序列?(是的,这不是Bresenham算法)@MBo老实说,我没有尝试过这种方法,但我会尝试一下,并让你知道结果。一种方法是交换ypur代码中的端点,这样你总是增加x(或者如果x在增加y时相等)/。这样,如果在调用中交换参数,代码会在内部将它们交换回来。你在哪里卡住了?你能显示一些代码吗?我添加了该方法。如果交换起始点和结束点,我需要得到相同的结果。链接主题的
ants280
方法是否产生相同的序列?(是的,这不是Bresenham算法)@MBo老实说,我没有尝试过这种方法,但我会尝试一下,并让你知道结果。一种方法是交换ypur代码中的端点,这样你总是增加x(或者如果x在增加y时相等)/。这样,如果在调用中交换参数,代码将在内部交换回参数。是的,我已经做了一个交换点的技巧,但你知道我更多地是寻找一种方法来获得唯一的结果,而不是这个技巧,因为内插点应该是从起点到终点的初始顺序,所以如果我在得到后交换起点和终点结果,我需要再次反转所有点,这需要花费一点时间。@Emad:loop backward(您需要计算err和y0的最终值,这是可行的).你的问题中没有告诉我这个要求。是的,我已经做了一个交换点的技巧,但是你知道我更多的是寻找一种方法来获得一个唯一的结果,而不是这个技巧,因为插值点应该是从起点到终点的初始顺序,所以如果我交换起点和终点,在得到结果后,我需要反转所有的po再次输入,这需要花费一点时间。@Emad:loop backward(您需要计算err和y0的最终值,这是可行的)。您在问题中没有说明这一要求。我没有说这是DDA必须采用的方式,增量版本仍然有效。我正在解释数学特性。我怀疑,如果小心一点,Bresenham算法也可以达到同样的效果。我没有说这是DDA必须采用的方式