获取两个像素之间的所有像素

时间:2013-11-09 11:50:15

标签: java math graphics path lines

我在java中编写了一个小型绘画程序,并且我在笔上插了一下:

Therory:当我拖动鼠标时,我必须用圆圈填充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);
        }
    }
}

它没有正常工作。有时奇怪的线条溅起来,圆圈没画,像这样:

paint fail

任何其他想法,如何解决? 谢谢!

3 个答案:

答案 0 :(得分:1)

Java不会为所有中间点生成事件 - 您可以通过在实际接收事件的每个地方绘制一个点来测试它。如果鼠标移动太快,错过点数。这种情况发生在所有绘图程序中。

Bresenham's line-drawing algorithm是在两个像素坐标之间查找整数像素的传统方法。但是你使用Java编程,并且你有更好的东西:你可以追踪通过坐标定义的任意路径。有两种口味,

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

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

新的基于形状的版本(g2d是Graphics2D;您在Swing中的Graphics可以毫无问题地转换为Graphics2D

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

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

答案 1 :(得分:0)

两个整数之间的除法丢弃小数部分:例如2/3返回0.您可以使用浮点类型进行计算以保留小数部分。

double m;
m = (double) (draggedY - mouseY) / (draggedX - mouseX);

答案 2 :(得分: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);
    }
}