中点画线算法的java实现

(好不容易排好版,结果复制上来就又乱了)    
“在数学上,理想的直线是没有宽度的,它是由无数个点构成的集合”。在计算机图形 学中,绘制线宽为一个像素的直线有三种常用算法:数值微分法(DDA)、中点画线法和 Bresenham 算法。这里,我是用 Java 中的 Applet 来实现中点画线算法。  
      设画直线过程中当前像素点为(𝑥𝑝,𝑦𝑝),下一个像素点有两个选择点𝑃1(𝑥𝑝 +1, 𝑦𝑝)𝑃2(𝑥𝑝+1 , 𝑦𝑝+1)。取中点 M=(𝑥𝑝+1 , 𝑦𝑝+0.5),Q 为理想直线与𝑥𝑝 +1 的交点。当 M 在 Q 的上 方时,取下点𝑃2;当 M 在 Q 点的下方时,取上点𝑃1。  
     直线的方程为F = (x,y) = ax + by + c = 0 ,a = 𝑦0 − 𝑦1,b = 𝑥1 − 𝑥0,c = 𝑥0𝑦1 − 𝑥1𝑦0 ,想要判断 M 在 Q 点的上方还是下方 
 (I)斜率小于 1 时:
需要构造判别式 d = F(M) = F(𝑥𝑝 + 1,𝑦𝑝 + 0.5) = 𝑎(𝑥𝑝 + 1) + 𝑏(𝑦𝑝 + 0.5) + c. 
设从点(𝑥0,𝑦0)开始画线,d 的初值𝑑0 = F(𝑥0 + 1,𝑦0 + 0.5) = F(𝑥0,𝑦0) + 𝑎 + 0.5𝑏,因为 F(𝑥0,𝑦0) = 0,所以𝑑0 = 𝑎 + 0.5𝑏.
 (1) 当d ≥ 0时,取正右方像素𝑃1(𝑥𝑝 +1, 𝑦𝑝)。判断下一个像素的位置时,应计算 𝑑1 = 𝐹(𝑥𝑝 + 2,𝑦𝑝 + 0.5) = 𝑎(𝑥𝑝 + 2) + 𝑏(𝑦𝑝 + 0.5) + c = d + a,增量为 a; 
(2) 当d < 0时,取右上方像素𝑃2(𝑥𝑝 +1, 𝑦𝑝 + 1)。判断下一个像素的位置时,应计算 𝑑2 = 𝐹(𝑥𝑝 + 2,𝑦𝑝 + 1.5) = 𝑎(𝑥𝑝 + 2) + 𝑏(𝑦𝑝 + 1.5) + c = d + a + b,增量为 a+b;
中点画线算法的java实现

 (II)斜率大于 1 时: 
需要构造判别式 d = F(M) = F(𝑥𝑝 + 0.5,𝑦𝑝 + 1) = 𝑎(𝑥𝑝 + 0.5) + 𝑏(𝑦𝑝 + 1) + c. 
设从点(𝑥0,𝑦0)开始画线,d 的初值𝑑0 = F(𝑥0 + 0.5,𝑦0 + 1) = F(𝑥0,𝑦0) + 0.5𝑎 + 𝑏,因为 F(𝑥0,𝑦0) = 0,所以𝑑0 = 0.5𝑎 + 𝑏.  
(1) 当d < 0时,取正上方像素𝑃1(𝑥𝑝 , 𝑦𝑝 + 1)。判断下一个像素的位置时,应计算 𝑑1 = 𝐹(𝑥𝑝 + 0.5,𝑦𝑝 + 2) = 𝑎(𝑥𝑝 + 0.5) + 𝑏(𝑦𝑝 + 2) + c = d + b,增量为 b;
 (2) 当d ≥ 0时,取右上方像素𝑃2(𝑥𝑝 +1, 𝑦𝑝 + 1)。判断下一个像素的位置时,应计算 𝑑2 = 𝐹(𝑥𝑝 + 1.5,𝑦𝑝 + 2) = 𝑎(𝑥𝑝 + 1.5) + 𝑏(𝑦𝑝 + 2) + c = d + a + b,增量为 a+b; 

控制台输入起始点和终止点坐标,applet程序呈现绘图

import java.applet.Applet;

import java.awt.Color;

import java.awt.Graphics;

import java.util.Scanner;

 

public class MidPoint extends Applet {

         int a[] = new int[4];

 

         public void init() {

                   setSize(300, 300);

                   Scanner sc = new Scanner(System.in);

                   System.out.println("input two point");

                   for (int i = 0; i < 4; i++) {

                            a[i] = sc.nextInt();

                   }

         }

 

         public void paint(Graphics g) {

                   g.setColor(Color.pink);

                   for (int i = 10; i <= 210; i += 10) {

                            g.drawLine(i, 10, i, 210);// 竖线

                            g.drawLine(10, i, 210, i);// 横线

                   }

                   g.setColor(Color.BLACK);

                   g.drawLine(10, 210, 220, 210);// x坐标

                   g.drawLine(10, 0, 10, 210);// y坐标

                   int x0 = a[0];

                   int y0 = a[1];

                   int x1 = a[2];

                   int y1 = a[3];

                   int a, b, d1, d2, d, x, y;

                   a = y0 - y1;

                   b = x1 - x0;

                   if (Math.abs(a / b) <= 1) {// 斜率绝对值小于1

                            d = 2 * a + b;

                            d1 = 2 * a;

                            d2 = 2 * (a + b);

                   } else {// 大于1

                            d = a + 2 * b;

                            d1 = 2 * b;

                            d2 = 2 * (a + b);

                   }

                   x = x0;

                   y = y0;

                   g.drawOval(x * 10 - 2 + 10, 210 - y * 10 - 2, 4, 4);// 起始点

                   if (Math.abs(a / b) <= 1) {// 斜率小于1

                            while (x < x1) {

                                     if (d < 0) {

                                               x++;

                                               y++;

                                               d += d2;

                                     } else {

                                               x++;

                                               d += d1;

                                     }

                                     g.drawOval(x * 10 - 2 + 10, 210 - y * 10 - 2, 4, 4);// 描点

                            }

                   } else {// 斜率大于1

                            while (y < y1) {

                                     if (d > 0) {

                                               x++;

                                               y++;

                                               d += d2;

                                     } else {

                                               y++;

                                               d += d1;

                                     }

                                     g.drawOval(x * 10 - 2 + 10, 210 - y * 10 - 2, 4, 4);// 描点

                            }

                   }

                   g.drawLine(x0 * 10 + 10, 210 - y0 * 10, x * 10 + 10, 210 - y * 10);// 画直线

         }

}

posted @ 2016-04-05 12:56  LOOKAUST  阅读(932)  评论(0)    收藏  举报