【问题标题】:Get a unique result from Bresenham algorithm从 Bresenham 算法获得独特的结果
【发布时间】:2018-03-02 01:09:09
【问题描述】:

我想使用Bresenham's algorihm 栅格化一行。我的插值顶点不应包含对角线步骤。我在 StackOverflow 上做了一些搜索,this topic 似乎正是我需要的东西。

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

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

//The thing I'm looking for
plotPoints(startPoint, endPoint)==plotPoints(endPoint, startPoint)

代码与The answer 几乎相同。但是我为我的目的做了一些定制:

        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;
        }

【问题讨论】:

  • 你卡在哪里了?你能显示一些代码吗?
  • 我添加了方法。如果我交换起点和终点,我需要得到相同的结果。
  • 链接主题的ants280 方法是否产生相同的序列? (是的,这不是 Bresenham 算法)
  • @MBo 老实说,我没有尝试过这种方法,但我会试一试,然后告诉你结果。
  • 一种方法是交换 ypur 代码中的端点,以便您始终增加 x(或者如果 x 等于增加 y)/。这样,如果您在调用中交换参数,内部代码会将它们交换回来。

标签: c# math computational-geometry


【解决方案1】:

正如 cmets 中所说,一个技巧是将输入标准化,这样如果您交换端点,它们将自动交换回来。

一种可能的方法是强制端点按字典顺序排列(最小的 X 在前,在平局的情况下,最小的 Y)。

【讨论】:

  • 是的,我已经做了一个交换点的技巧,但是你知道我更多的是寻找一种方法来获得一个独特的结果而不是这个技巧,因为插值点应该按照开始的初始顺序到端点,所以如果我交换开始和结束,在我得到结果后,我需要再次反转所有点,这需要一点时间。
  • @Emad:向后循环(您需要计算 err 和 y0 的最终值,这是可行的)。您没有在问题中说明此要求。
【解决方案2】:

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

X = X0 + (k.DX) rnd D
Y = Y0 + (k.DY) rnd D

其中D = max(|DX|, |DY|)rnd 是舍入运算,k0 变为D

如果您交换端点,则增量会更改符号并进行交易

Y0 + (k.DY) rnd D

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

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


要做到这一点,rnd 操作必须享有平移不变性属性rnd(x+n) = rnd(x)+n,它对应于(k.DY) rnd D = floor((k.DY + S) / D),其中S 是一些舍入偏移量(通常是@987654333 @ 或 D&gt;&gt;1)。

【讨论】:

  • 我没有说DDA必须这样实现,增量版本仍然成立。我正在解释数学特性。我怀疑 Bresenham 算法可以得到相同的行为。
猜你喜欢
  • 2019-12-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多