基于java图形学实践记录(The First Day)

 

Assignment ;因为java的坐标系和习惯的坐标系不一样(Y轴正方向向下),所以要先建立自己的坐标。

为了达到这个目的,实现方法的思路大概是这样:自己的坐标系->视图->java坐标系(这三家伙两两之间的转换都是根据比例建立变换关系的).

CODE:

MyCanvas.java(我的画布类)

My View:注释都很详细,大家应该能看明白.

哦,要注意的一点是:在视图->java坐标系中,Y轴的变换有点特别.

一般屏幕坐标系是直角左手系,y轴方向向下为正,原点在屏幕的左上角.解释窗口内图形上任一点(x,y)变换到视口内成为(sx,xy),而(x,y)是相对用户坐标系(直角右手系)的。(sx,sy)是相对屏幕坐标系(直角左手系)的,因此y轴方向相反。为使窗口内图形变换到视口上图形其形状一致,需将视口上图形y轴方向变换成窗口内图形y轴方向。这只要将求得的视口内各点的sy整型坐标均用sy2去减,即sy2-sy(整型)代替sy(整型)即可,经这样的坐标轴方向变换后得到的视口内图形与窗口内图形一致。

程序中使用的是:1-y.

 

 

// MyCanvas.java

import  java.awt. * ;
import  java.awt.image. * ;
public   class  MyCanvas  extends  Component {
    
//自定义坐标系范围
    protected double userMinX = -1;//X轴的最小值
    protected double userMaxX = 1;//x轴的最大值
    protected double userMinY = -1;//Y轴的最小值
    protected double userMaxY = -1;//Y轴的最小值
    
    
//视图范围The range of view
    protected double[] viewMinX;//X轴的最小值
    protected double[] viewMaxX;//x轴的最大值
    protected double[] viewMinY;//Y轴的最小值
    protected double[] viewMaxY;//Y轴的最小值
    final static int DefaultViewportMax = 256;//缺省试图数
    protected int viewportMax = DefaultViewportMax;//视图数
    protected int viewportNum = 0;//当前视图数
    protected int currentViewport = 0;//当前试图的索引
    
    
//窗口大小The size of window
    final static int DefaultWindowSize = 256;//缺省的窗口大小
    protected int windowWidth = DefaultWindowSize;//窗口宽度
    protected int windowHeight = DefaultWindowSize;//窗口高度
    
    
//Graphic and its Component
    protected Graphics myGraphics;//Graphic类数据
    protected Component myComponent;//Component类数据
    protected Color currentFrontColor = Color.white;//当前颜色
    protected Color currentBackColor = Color.black;//当前背景色
    
    
//构造器
    public MyCanvas(Component a){
        myComponent 
= a;//设定MyCanvas类用的Component
        myGraphics = a.getGraphics();//设定MyCanvas用的Graphics
        windowWidth = a.getSize().width;//窗口宽度
        windowHeight = a.getSize().height;//窗口高度
        createViewport(DefaultViewportMax);//创建视图
    }

    
private void createViewport(int max){
      currentViewport 
= 0;//视图索引的初始值设定
      viewportMax = max;//设定视图数的最大值
      viewMinX = new double[viewportMax];//视图X轴的最小值数组
      viewMaxX = new double[viewportMax];//视图X轴的最大值数组
      viewMinY = new double[viewportMax];//视图Y轴的最小值数组
      viewMaxY = new double[viewportMax];//视图Y轴的最大值数组
      viewMinX[0= viewMinY[0= 0.0;//视图的最小值为0
      viewMaxX[0= viewMaxY[0= 1.0;//视图的最大值为1
      viewportNum = 1;//视图的当前索引为1
    }

    
//自定义坐标系的范围的设定
    public void setMyWindow(double x1,double x2,double y1,double y2){
        userMinX 
= x1;//窗口的X轴的最小值设定
        userMaxX = x2;//窗口的X轴的最大值设定
        userMinY = y1;//窗口的Y轴的最小值设定
        userMaxY = y2;//窗口的Y轴的最大值设定
    }

    
//视图的设定
    public void setViewport(double x1,double x2,double y1,double y2){
        viewMinX[viewportNum] 
= x1;//视图的X轴的最小值设定
        viewMaxX[viewportNum] = x2;//视图的X轴的最大值设定
        viewMinY[viewportNum]    = y1;//视图的Y轴的最小值设定
        viewMaxY[viewportNum] = y2;//视图的Y轴的最大值设定
        currentViewport = viewportNum;//当前视图索引的设定
        viewportNum++;//视图数加1
    }

    
/****视图的复位****/
    
public void resetViewport(){
      currentViewport 
= 0;//视图索引返回到0
      viewMinX[0= viewMinY[0= 0.0;//视图的最小值为0
      viewMaxX[0= viewMaxY[0= 1.0;//视图的最大值为1
      viewportNum = 1;//视图数为1
    }

    
/****将视图坐标转换到java AWT坐标方法***/
    
public int getIntX(double x){
        
return (int)(windowWidth * x);
    }
//窗口宽度加倍
    public int getIntY(double y){
        
return (int)(windowHeight * (1 - y));
    }
//窗口高度加倍
    /*******将自定义坐标转换到视图坐标**********/
    
public double viewX(double x){
       
double s = (x - userMinX)/(userMaxX - userMinX);
       
double t = viewMinX[currentViewport] + s *
                   (viewMaxX[currentViewport] 
- viewMinX[currentViewport]);
       
return t;    
    }

    
public double viewY(double y){
        
double s = (y - userMinY)/(userMaxY - userMinY);
        
double t = viewMinY[currentViewport] + s *
        (viewMaxY[currentViewport] 
- viewMinY[currentViewport]);
        
return t;
    }

    
/*******将自定义坐标转换到java AWT坐标********/
    
public int getX(double x){
      
double xx = viewX(x);//x转换到视图坐标
      int ix = getIntX(xx);//视图转换到java坐标
      return ix;    
    }

    
public int getY(double y){
      
double yy = viewY(y);//y转换到视图坐标
      int iy = getIntY(yy);//视图转换到java坐标
      return iy;    
    }

    
/******得到Dimension(维数)的方法**********/
    
public int getDimensionX(double w){
        
double x = viewMaxX[currentViewport] - viewMinX[currentViewport];
        x 
*= windowWidth * w / (userMaxX - userMinX);
        
return((int)Math.abs(x));
    }

    
public int getDimensionY(double h){
        
double y = viewMaxY[currentViewport] - viewMinY[currentViewport];
        y 
*= windowHeight * h / (userMaxY - userMinY);
        
return((int)Math.abs(y));
    }

    
/*****颜色设定方法******/
    
public Color getColor(){return currentFrontColor;}//当前的颜色检索
    public void setColor(Color c){
        myGraphics.setColor(c);
        currentFrontColor 
= c;//当前颜色设定
    }

    
public Color getForeground(){return currentFrontColor;}//前面颜色检索
    public void setForeground(Color c){//前面颜色设定
       myComponent.setForeground(c);
       currentFrontColor 
= c;    
    }

    
public Color getBackground(){return currentBackColor;}//背景颜色检索
    public void setBackground(Color c){
       myComponent.setBackground(c);
       currentBackColor 
= c;//背景颜色设定    
    }

    
/*******************
    ***直线描画方法
    *******************
*/

    
public void drawLine(double x1,double y1,double x2,double y2){
        
//转换到java坐标系值
        int ix1 = getX(x1);
        
int iy1 = getY(y1);    
        
int ix2 = getX(x2);
        
int iy2 = getY(y2);
        myGraphics.drawLine(ix1,iy1,ix2,iy2);
    }

    
/*******************
    ***文字列的描画
    *******************
*/

    
public void drawString(String str,double x,double y){
      
int ix = getX(x);//自定义坐标轴到java坐标轴
      int iy = getY(y);//自定义坐标轴到java坐标轴
      myGraphics.drawString(str,ix,iy);    
    }

    
/*******************
    ***多边形的填充
    *******************
*/

    
public void fillPolygon(double[] x,double[] y,int numPoints){
        
int[] ix = new int[numPoints];
        
int[] iy = new int[numPoints];
        
for(int i=0;i<numPoints;i++){
          ix[i] 
= getX(x[i]);//自定义坐标轴到java坐标轴
          iy[i] = getY(y[i]);//自定义坐标轴到java坐标轴
        }

        myGraphics.fillPolygon(ix,iy,numPoints);
    }

}

 

MyCoordinate.java(测试类)

// <applet   code=MyCoordinate   width   =300   height   =300>   
  
// </applet>


// MyCoordinate.java
import  java.awt. * ;
import  java.applet.Applet;



public   class  MyCoordinate  extends  Applet {
     
     MyCanvas m;
//MyCanvas用数据
     final static int idealSizeX = 600;
     
final static int idealSizeY = 350;
   
public void init(){m = new MyCanvas(this);}//生成myCanvas 对象    
   public void paint(Graphics g){
      m.setBackground(
new Color(200,200,200));
      m.setColor(Color.black);
      m.setViewport(
0.1,0.9,0.1,0.9);//设定视图范围坐标[0,1]*[0,1]
      m.setMyWindow(-1,1,-1,1);//设定自定义坐标系范围
   
      
      
//画X轴
      double[] x1 = {0.95,1.0,0.95};//箭头的坐标值
      double[] y1 = {-0.05,0.0,0.05};//箭头的坐标值
      m.drawLine(-1,0,1,0);//画X轴 
      m.fillPolygon(x1,y1,3);//填充箭头
      m.drawString("x轴",0.8,-0.2);//标注"X轴"
      
//画y轴
      double[] x2 = {-0.05,0.05,0.0};//箭头的坐标值
      double[] y2 = {0.95,0.95,1.0};//箭头的坐标值
      m.drawLine(0,-1,0,1);//画X轴 
      m.fillPolygon(x2,y2,3);//填充箭头
      m.drawString("y轴",-0.2,0.9);//标注"X轴"
      
      
      
      m.resetViewport();
   }

}

RUN:

 My View:能看到的在MyCoordinate.java的顶端有这么一段"//<applet   code=MyCoordinate   width   =300   height   =300>    //</applet>" 目的是在命令行中直接运行Applet.

  而在编译时也有点问题,用下图的命令可得到比较好的解决。

运行命令:

 

运行结果:

闪……

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Eclipse平台JAVA实现 1. 实验内容 用基本增量算法和Bresenham算法画直线 2.实验目的 1)理解在显示器上画图与在纸上画图的本质区别; 2)掌握直线的光栅扫描转换过程; 3)掌握不同算法绘制直线的思路和优缺点。 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入参数; 3)鼠标移动时,显示鼠标当前位置; 4)显示判别式的计算过程和下一点的选择策略; 5)记录生成点的坐标,建议用表的形式; 6)图形生成过程可以重复进行。 1. 实验内容 用正负法和Bresenham算法画圆弧 2.实验目的 1)掌握圆及圆弧的光栅扫描转换过程; 2)掌握不同算法绘制圆弧的技巧和优缺点。 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入参数; 3)鼠标移动时,显示鼠标当前位置; 4)显示判别式的计算过程和下一点的选择策略; 5)记录生成点的坐标,建议用表的形式; 6)图形生成过程可以重复进行。 1. 实验内容 用Cohen-SutherLand算法和liang _barsky算法进行线段裁剪 2.实验目的 1)理解裁剪的相关概念 2)掌握直线段的一般裁剪过程; 3)理解并掌握Cohen-SutherLand 算法的编码思想; 4)理解并掌握Liang_Barsky算法的参数化裁剪思想; 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入剪裁线段和裁剪窗口; 3)鼠标移动时,显示鼠标当前位置; 4)对于线段裁剪,线段被窗口的四条边裁剪的过程要显示出来; 6)裁剪过程可以重复进行。 1. 实验内容 用Sutherland-Hodgman算法进行多边形裁剪 2.实验目的 1)理解多边形裁剪与直线段裁剪的区别; 2)掌握多边形的裁剪过程; 3)理解并掌握Sutherland-Hodgman算法的裁剪思想。 3. 实验要求 1)将像素网格表现出来,建立网格坐标系; 2)用橡皮筋的形式输入剪裁多边形和裁剪窗口; 3)鼠标移动时,显示鼠标当前位置; 4)多边形被窗口的四条边裁剪的过程以及多边形顶点增删的过程要显示出来; 5)裁剪过程可以重复进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值