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.
而在编译时也有点问题,用下图的命令可得到比较好的解决。
运行命令:

运行结果:

闪……