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 的画线算法是寻找两个像素坐标之间的整数像素的传统方法。但是您正在使用 Java 编程,并且您拥有更好的东西:您可以跟踪通过坐标定义的任意路径。有两种口味,

旧的 Graphics 版本( g 是 a Graphics,可能来自您的paintComponent()方法):

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

以及新的基于 Shape 的版本(g2d 是一个Graphics2D; 你Graphics在 Swing 中可以Graphics2D毫无问题地转换):

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

我推荐第二个版本,因为笔画提供了更多的灵活性(线宽,虚线,......)而不仅仅是简单的颜色

于 2013-11-09T17:14:29.590 回答
0

除了其他答案所说的之外,如果 的绝对值m大于 1,您还需要以不同的方式进行绘图。如果它是 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/3 返回 0。您可以使用浮点类型进行计算以保留小数部分。

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