光栅图形学之直线段扫描算法(中点画线法之java代码)

说明:本文章系作者学习资料整理,不完善的地方请大家指正,谢谢!

//DrawLine.java

import javax.swing.*;
import java.awt.*;

public class  DrawLineDemo
{
 public static void main(String[] args)
 { 

  CheckJFrame cjf = new CheckJFrame();
 
    }
}

class DrawLine extends JFrame
{
      
 public DrawLine()
 {
  setSize(600,600); //设定窗口的初始大小
  setVisible(true); //设定窗口可见
  setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//设定关闭窗口的同时,程序推出运行
  
 }
      
 public   void   paint(Graphics   g){   //自动调用paint函数 
      super.paint(g);//********继承父类的画图的方法  不用hold on就能在图上继续画图,而不会重绘
   Axis   axisX = new   Axis();  //新建座标系对象
      axisX.setTickX(100);          //设定直角座标系的原点
      axisX.setTickY(500);          //在图像中是以像素为单位,且需进行座标转换
      axisX.setTickCount(20);       //设定将座标轴分成几份
      axisX.setTickLength(400);     //设定座标轴长度
      axisX.setTickStep(20);        //设定步长,即间隔
     int   XtickX=axisX.getTickX();     
     int   XtickY=axisX.getTickY();  
     int   XtickLength=axisX.getTickLength();  
     int   XtickCount=axisX.getTickCount();  
     int   XtickStep=axisX.getTickStep();  

   //新建一个Givepoint类,
       Givenpoint m = new Givenpoint(); //生成一个对象,给出两个已知点

    m.setx0(2);   //设定直角座标系中的第一个点的横座标
    m.setx1(9);   //设定直角座标系中的第二个点的横座标
    m.sety0(2);   //设定直角座标系中的第一个点的纵座标
       m.sety1(10);  //设定直角座标系中的第二个点的纵座标

     int x0=m.getx0();
     int x1=m.getx1();
  int y0=m.gety0();
  int y1=m.gety1();
      
//利用两个for循环嵌套来实现画格网
//分别画纵座标轴和横座标轴  实际上就是画多条平行线和垂直线
//用到了Graphics类中的drawLine函数:drawLine(x0,y0,x1.y1) 代表直线的起点和终点

 for (int j = XtickY;j > XtickY-XtickLength ;j -= XtickStep )
 {
  g.drawLine(XtickX,j,XtickX+XtickLength,j);
 }
 for (int i = XtickX;i < XtickX+XtickLength ; i += XtickStep)
 {
  g.drawLine(i,XtickY,i,XtickY-XtickLength);
 }

 //存在像素座标和直角座标的转换
 //drawOval(int x,int y,int width,int height)函数功能是生成一个椭圆或圆,
 //其外接矩形是以(x,y)为左上角,以width为宽度,以height为高度。

    int  dx = x1-x0, dy = y1-y0 ;
    int  x=x0 , y=y0; 
    int screenX = 20*x + XtickX;
    int screenY = XtickY - 20*y;
    g.drawOval(screenX-5,screenY-5,10,10);
//double k=dy/dx;***********************************考虑一下

 //第一种情况
   if ((dy+0.5)/dx > 0& (dy+0.5)/dx <= 1) {
   int d0 = dx-2*dy,d1 = -2*dy,d2 = 2*(dx - dy);
    while (x<x1){
    if(d0 > 0) { x++; d0 += d1;}
    else { x++;y++; d0 += d2; }

     screenX = 20*x + XtickX;
     screenY = XtickY - 20*y;
    g.drawOval(screenX-5,screenY-5,10,10);
}

}   

//第二种情况

    else  if ((dy+0.5)/dx >= -1&& (dy+0.5)/dx <= 0) {
    int d0 = -dx - 2*dy, d1 = -2*(dx+dy), d2 = -2*dy;
    while(x < x1) {
    if(d0 > 0) { x++; y--; d0 += d1;}
    else { x++; d0 += d2;}
     screenX = 20*x + XtickX;
     screenY = XtickY - 20*y;
   g.drawOval(screenX-5,screenY-5,10,10);
}                                                                               

}
// 第三种情况
    else if((dy+0.5)/dx >1) {
   int d0=2*dx-dy,d1=2*(dx-dy),d2=2*dx;
   while (y < y1)
   {
    if(d0 > 0)
    {x++;y++;d0 += d1;}
    else
    {y++;d0 += d2;}
    screenX = 20*x + XtickX;
       screenY = XtickY - 20*y;
       g.drawOval(screenX-5,screenY-5,10,10);

   }
}

//第四种情况

     else if ((dy+0.5)/dx < -1) {
     int d0 = -2*dx - dy,d1 = -2*dx, d2 = -2*(dx+dy);
     while (y > y1) {
       if(d0 > 0) {y -- ;d0 += d1;}
       else { y --; x++; d0 += d2;}
     screenX = 20*x + XtickX;
     screenY = XtickY - 20*y;
    g.drawOval(screenX-5,screenY-5,10,10);

}
}

}
}

//Axis.java

public class  Axis
{
  private   int   tickX;//横座标的起始点 即座标轴的起始点的横座标 
  private   int   tickY;//纵座标的起始点 即座标轴的起始点的纵座标
  private   int   tickLength;//座标轴长度  
  private   int   tickCount;//刻度的个数  
  private   int   tickStep;//刻度的步长

  int   getTickX(){          //得到座标轴原点横座标
  return   tickX;  
  }  
   
  void   setTickX(int   tickX){ //设置座标轴原点横座标
  this.tickX=tickX;  
  }  
  int   getTickY(){             //得到座标轴原点纵座标
  return   tickY;  
  }  
  void   setTickY(int   tickY){   //设置座标轴原点纵座标
  this.tickY=tickY;  
  }  
   
  int   getTickLength(){         //得到座标轴的长度
  return   tickLength;  
  }  
                           
  void   setTickLength(int   tickLength){  //设置座标轴的长度
  this.tickLength=tickLength;  
  }  
  int   getTickCount(){                  //得到间隔数量
  return   tickCount;  
  }  
  void   setTickCount(int   tickCount){   //设置间隔数量
  this.tickCount=tickCount;}  
   
  int   getTickStep(){                     //得到间隔距离
  return   tickStep;  
  }  
   
  void   setTickStep(int   tickStep){      //设置间隔距离
  this.tickStep=tickStep;  
  }    
}

//Givenpoint.java

public class Givenpoint
{

 public int x0;
 public int x1;
 public int y0;
 public int y1;

 
  int   getx0(){          //得到直角座标系的第一点的横座标
  return   x0;  
  }  
   
  void   setx0(int   x0){ //设置第一点的横座标
  this.x0=x0;  
  }  
  int   getx1(){             //得到第二点的横座标
  return   x1;  
  }  
  void   setx1(int  x1){   //设置坐第二点的横座标
  this.x1=x1;  
  }  
   
  int   gety1(){         //得到第二点的纵座标
  return   y1;  
  }  
                           
  void   sety1(int   y1){  //设置第二点的纵座标
  this.y1=y1;  
  }  
  int   gety0(){             //得到第一点的纵座标
  return  y0;  
  }  
  void   sety0(int   y0){   //设置第一点的纵座标
  this.y0=y0;}  

}

注意:

可以改进的方向是:

1 在直角座标系上表明座标和箭头

2 使得画的直角座标系适用于所有象限

3 能够人机交互的输入数据

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章