在Java中创建坡度
我正在尝试用java创建一个斜坡。我可以使用DrawLine函数,它将创建一个完美的函数,但我不想使用它,而是为它创建我自己的函数。问题是它在点之间有间隙在Java中创建坡度,java,Java,我正在尝试用java创建一个斜坡。我可以使用DrawLine函数,它将创建一个完美的函数,但我不想使用它,而是为它创建我自己的函数。问题是它在点之间有间隙 import java.applet.Applet; import java.awt.Graphics; public class slope extends Applet{ public void drawLine(int x1, int y1, int x2, int y2, Graphics g) {
import java.applet.Applet;
import java.awt.Graphics;
public class slope extends Applet{
public void drawLine(int x1, int y1, int x2, int y2, Graphics g) {
double m = (y2 - y1) / (double)(x2-x1);
double y = y1;
for (int x =x1; x < x2; x++) {
drawPoint(x,(int)y,g);
y +=m;
}
}
public void paint(Graphics g) {
drawLine(20, 10, 300, 700, g); //has spaces between the dots
g.drawLine(20, 10, 300, 700); //this is perfect
}
private void drawPoint(int x, int y, Graphics g) {
g.drawLine(x, y, x, y);
}
}
import java.applet.applet;
导入java.awt.Graphics;
公共类斜坡扩展小程序{
公共空白绘制线(图x1、图y1、图x2、图y2、图g){
双m=(y2-y1)/(双)(x2-x1);
双y=y1;
对于(int x=x1;x
两个循环:仅当deltaX>deltaY时才在x++上循环。 否则您只能在y++上循环 在同一个循环中,双步进x和y,决定哪个应该递增(假设x也是y的函数),由于额外的测试和相邻像素可能看起来像线中的点,可能会导致绘制速度变慢。您需要使用颜色强度来手动执行抗锯齿(镀金)。两个循环要简单得多
仅供参考,如果您试图生成图像,也可以在矩阵中设置int,然后生成屏幕外的原始图像(BuffereImage及其.setRGB()方法),稍后再绘制。这可能会更快,并避免可见的绘制延迟。通常,这是通过使用一种算法来完成的,该算法不仅沿x或y轴进行步进,还可以通过可变量调整更新增量,使每个点彼此之间的距离最多为
sqrt(2)
因此,如果您认为在x值处有一个点,但当您计算它时,您发现它距离3.5像素(因为斜率非常陡峭),那么您将陷入一个例程,该例程计算(通常递归地)x步长之间的中间像素
(x, y)
(0, 0) to (1, 5) distance 5.09
-> fill routine
(0, 0) to (0.5, 2.5) distance 2.69
-> fill routine
(0, 0) to (0.25, 1.25) distance 1.34 < 1.41
(0.25, 1.25) to (0.5, 2.5) distance 1.34 < 1.41
(0.5, 2.5) to (0.75, 3.75) distance 1.34 < 1.41
(0.75, 3.75) to (1, 5) distance 1.34 < 1.41
(1, 5) to (2, 10) etc...
(x,y)
(0,0)至(1,5)距离5.09
->填充程序
(0,0)至(0.5,2.5)距离2.69
->填充程序
(0,0)到(0.25,1.25)距离1.34<1.41
(0.25,1.25)到(0.5,2.5)距离1.34<1.41
(0.5,2.5)到(0.75,3.75)距离1.34<1.41
(0.75,3.75)到(1,5)距离1.34<1.41
(1,5)至(2,10)等。。。
使用1.41(sqrt(2))作为允许的最大距离的原因是,与屏幕底部成45度角的一组像素看起来仍然是连接的
现在,在打印中,需要将值舍入以与精确的像素对齐。有很多方法可以做到这一点。最简单的方法就是四舍五入到下一个有效值,这在大多数情况下都有效。它确实有一个不幸的副作用,那就是你的线条看起来会有锯齿状的台阶(如果圆角移动的像素越多,台阶就会显得越锯齿状)。这种锯齿称为“锯齿”,因为真实点通过点的非真实表示(别名)呈现
第二种方法是根据点的接近程度,按比例交替地使两个像素变暗。x轴上位于(0.5)的点将使两个像素变暗50%,而位于(0.25)的点将使0像素变暗75%,使1像素变暗25%。这是消除混叠,可能会导致线条稍微模糊,但看起来更直。这种模糊性可以通过画一条粗线来消除
我希望这能让您了解许多高质量绘图例程背后的数学原理,当然还有比我刚才介绍的更复杂的方法。基于该算法,下面是一个java实现
假设x2>x1和y2>y1
,并使用整数算术
import java.applet.Applet;
import java.awt.*;
public class Slope extends Applet{
private int x1 = 20, y1 = 10;
private int x2 = 300, y2 = 700;
@Override
public void paint(Graphics g) {
drawLine(x1, y1, x2, y2, g);
//g.drawLine(x1, y1, x2, y2, g);
}
private void drawPoint(int x, int y, Graphics g) {
g.drawLine(x,y,x,y);
}
@Override
public void init(){
this.setSize(500,700);
}
private void drawLine(int x1,int y1,int x2,int y2,Graphics g){
int dx = x2 - x1;
int dy = y2 - y1;
int xi = 1;
int D = 2*dx - dy;
int x = x1;
for(int y = y1; y <y2; y++) {
drawPoint(x,y,g);
if(D > 0) {
x = x + xi;
D = D - 2 * dy;
}
D = D + 2 * dx;
}
}
}
import java.applet.applet;
导入java.awt.*;
公共类斜坡扩展小程序{
私有整数x1=20,y1=10;
私有整数x2=300,y2=700;
@凌驾
公共空间涂料(图g){
抽绳(x1、y1、x2、y2、g);
//g、 抽绳(x1、y1、x2、y2、g);
}
专用空心绘图点(整数x、整数y、图形g){
g、 抽绳(x,y,x,y);
}
@凌驾
公共void init(){
这个。设置大小(500700);
}
专用虚线(图x1、图y1、图x2、图y2、图g){
int dx=x2-x1;
int dy=y2-y1;
int席=1;
int D=2*dx-dy;
int x=x1;
对于(int y=y1;y 0){
x= x+席;
D=D-2*dy;
}
D=D+2*dx;
}
}
}
根据角度的不同,您应该在
x
或y
上迭代。它没有“点之间的间隙”。这根本不是一条线。你画的是单个的点,为什么你希望它们是相互连接的呢?@f1sh他在问如何在没有间隙的情况下做到这一点。所有的线实际上都是点,只是没有间隙。好吧,如果m
大于1,那么很明显,你会有间隙,所以你需要检查y
并将1/m
添加到x
。如果你注意到你也需要处理负值,那就需要额外加分。当然,我的方法和user2023577都会遇到垂直线等问题。但是如果你采用任何一种方法,很可能你可以轻松处理这些问题。一般来说,它是通过假装一个极小的斜率来完成的,这个斜率在屏幕上是看不到的,但是它足够大,可以避免被零除的错误