1

私はJavaで小さなペイントプログラムを書いていますが、ペンにこだわっています:

理論: マウスをドラッグするとき、P(draggedX|draggedY) と P2(mouseX|mouseY) の間の円を円で埋める必要があります。したがって、線/パス (?..) を作成し、その上にあるすべての点を計算する必要があります。

試したこと:

double m = 0;
int width = draggedX - mouseX;
int height = draggedY - mouseY;
if(draggedX - mouseX != 0){
    m = (draggedY - mouseY) / (draggedX - mouseX);
}
if(width > 0){
    for(int i = 0; i < width; i++) {
        double x = mouseX + i;
        double y = mouseY + (m * i);
        g.fillOval((int) x, (int) y, 5, 5);
    }
}
else if(width < 0){
    for(int i = -width; i > 0; i--) {
        double x = mouseX + i;
        double y = mouseY + (m * i);
        g.fillOval((int) x, (int) y, 5, 5);
    }
}
else{
    if(height > 0){
        for(int i = 0; i < height; i++){
            g.fillOval(mouseX, (int) i + mouseY, 5, 5);
        }
    }
    else if(height < 0){
        for(int i = -height; i > 0; i--){
            g.fillOval(mouseX, (int) i + mouseY, 5, 5);
        }
    }
}

正しく動作しませんでした。次のように、奇妙な線が飛び散り、円が描画されないことがありました。

塗装失敗

他のアイデア、それを解決する方法はありますか? ありがとうございました!

4

3 に答える 3

1

Java は、すべての中間点に対してイベントを生成するわけではありません。実際にイベントを受け取る各場所に点を描画することで、これをテストできます。マウスの動きが速すぎると、ポイント逃してしまいます。これは、すべての描画プログラムで発生します。

Bresenham の線描画アルゴリズムは、2 つのピクセル座標間の整数ピクセルを見つける従来の方法です。しかし、Java でプログラミングしている場合、はるかに優れたものがあります。座標によって定義された任意のパスをトレースできます。2種類のフレーバーをご用意しております、

古い Graphics バージョン ( g はGraphics、おそらくpaintComponent()メソッドからの ):

// uses current g.setColor(color)
g.drawPolyline(xPoints, yPoints, int nPoints); // xPoints and yPoints are integer arrays

そして、新しい Shape ベースのバージョン (g2d はGraphics2Dです。Swing では問題なくGraphicsキャストできますGraphics2D):

// uses current stroke
g2d.draw(p); // p is a Path2D, build with successive moveTo(point) and lineTo(point)

2 番目のバージョンをお勧めします。これは、ストロークが単純な色よりもはるかに柔軟 (線幅、ダッシュなど) であるためです。

于 2013-11-09T17:14:29.590 に答える
0

他の回答が言ったことに加えて、の絶対値がm1より大きいかどうかにかかわらず、描画を別の方法で行う必要もあります。1 以下の場合は、x 方向に沿って反復し、勾配から y を計算します。それ以外の場合は、y 方向に沿って反復し、(逆) 勾配から m を計算する必要があります。コードには正しい考えがありますが、正しく実装されていません。次のようになります。

if (abs(m) <= 1)
{
    for (int i = startX; i < endX; i++)
    {
        float y = startY + (float)i * m;
        float x = i;
        g.fillOval(x, y, 5, 5);
    }
}
else
{
    for (int i = startY; i < endY; i++)
    {
        float x = startX + (float)i / m;
        float y = i;
        g.fillOval(x, y, 5, 5);
    }
}
于 2013-11-09T16:38:06.807 に答える
0

2 つの整数の除算では、小数部分が破棄されます。たとえば、2/3 は 0 を返します。計算に浮動小数点型を使用して、小数部分を保持できます。

double m;
m = (double) (draggedY - mouseY) / (draggedX - mouseX);
于 2013-11-09T12:15:12.443 に答える