我在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);
}
}
}
它没有正常工作。有时奇怪的线条溅起来,圆圈没画,像这样:
任何其他想法,如何解决? 谢谢!
答案 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);
}
}