光栅图形学之直线段扫描算法(中点画线法之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 能够人机交互的输入数据

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值