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

来源:互联网 发布:笔记本强制散热软件 编辑:程序博客网 时间:2024/06/06 07:37

 

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.

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

运行命令:

 

运行结果:

闪……

原创粉丝点击