-1

私は現在、開発中のタイルベースのワールドエディタにブレゼンハムラインアルゴリズムを実装しています。Shift+機能についてClickは、タイルセットからの選択長方形に基づいて線をレンダリングしたいと思います。アルゴリズムpoint1を使用してからまでの線上の点を見つけ、各点で選択範囲を描くことができるので、これは簡単です。point2

これに関する問題は、選択長方形が1タイルよりも大きい場合、ポイントが重なることです。結果は以下のようになります。

現在

私の質問には、ライン上のすべてのポイントと選択サイズが示されていますが、どうすればこのような結果を得ることができますか?を超えたら、選択範囲の描画を停止したいことに注意してくださいpoint2

望ましい

これが、選択サイズに関係なく線をレンダリングするために現在持っているものです。

void renderPoint(Point point, bool invalidate = false)
{
    Rectangle selection = world.SelectionRectangle;

    int width = selection.Width / world.Settings.TileSize.Width,
        height = selection.Height / world.Settings.TileSize.Height,
        offsetX = (int)Math.Floor((float)width / 2),
        offsetY = (int)Math.Floor((float)height / 2);

    for (int x = point.X, sx = 0; x < point.X + width; x++, sx++)
    {
        for (int y = point.Y, sy = 0; y < point.Y + height; y++, sy++)
        {
            Point change = new Point(x - offsetX, y - offsetY);

            if (!changesUndo.ContainsKey(change))
                changesUndo[change] = world.GetTile(change);

            WorldTile tile = new WorldTile(selection.X + (sx * world.Settings.TileSize.Width), selection.Y + (sy * world.Settings.TileSize.Height), 0);

            world.SetTile(change.X, change.Y, tile);

            changesRedo[change] = tile;
        }
    }

    lastRenderedPoint = point;

    if (invalidate)
        world.InvalidateCanvas();
}

void renderLine(Point p1, Point p2)
{
    List<Point> points = pointsOnLine(p1, p2);

    for (int i = 0; i < points.Count; i++)
        renderPoint(points[i], i == points.Count - 1);
}

私のコードのコンテキストがもっと必要な場合は、コメントを残してください。

4

1 に答える 1

1

ポイントがブレゼンハムでレンダリングされる場合は、「n」ポイントからすべての「n-1」をスキップする必要があります。ここで、「n」は線の主方向の選択サイズです(つまり、ほとんどが水平線の場合、幅)。

このようなもの?:

void renderLine(Point p1, Point p2)
{
    List<Point> points = pointsOnLine(p1, p2);

    int dx = Abs(p2.x - p1.x);
    int dy = Abs(p2.y - p1.y);

    Rectangle selection = world.SelectionRectangle;

    int incr = selection.Width / world.Settings.TileSize.Width;
    if(dy > dx)
    {
        incr = selection.Height / world.Settings.TileSize.Height;
    }

    int lastPoint = (points.Count-1) / incr;
    lastPoint *= incr;

    for (int i = 0; i <= lastPoint; i+=incr)
        renderPoint(points[i], i == lastPoint);
}
于 2012-12-23T09:09:10.733 に答える