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

importjava.awt.*;
importjava.awt.image.*;

publicclassMyCanvasextendsComponent...{
//自定义坐标系范围
protecteddoubleuserMinX=-1;//X轴的最小值
protecteddoubleuserMaxX=1;//x轴的最大值
protecteddoubleuserMinY=-1;//Y轴的最小值
protecteddoubleuserMaxY=-1;//Y轴的最小值

//视图范围Therangeofview
protecteddouble[]viewMinX;//X轴的最小值
protecteddouble[]viewMaxX;//x轴的最大值
protecteddouble[]viewMinY;//Y轴的最小值
protecteddouble[]viewMaxY;//Y轴的最小值
finalstaticintDefaultViewportMax=256;//缺省试图数
protectedintviewportMax=DefaultViewportMax;//视图数
protectedintviewportNum=0;//当前视图数
protectedintcurrentViewport=0;//当前试图的索引

//窗口大小Thesizeofwindow
finalstaticintDefaultWindowSize=256;//缺省的窗口大小
protectedintwindowWidth=DefaultWindowSize;//窗口宽度
protectedintwindowHeight=DefaultWindowSize;//窗口高度

//GraphicanditsComponent
protectedGraphicsmyGraphics;//Graphic类数据
protectedComponentmyComponent;//Component类数据
protectedColorcurrentFrontColor=Color.white;//当前颜色
protectedColorcurrentBackColor=Color.black;//当前背景色

//构造器

publicMyCanvas(Componenta)...{
myComponent=a;//设定MyCanvas类用的Component
myGraphics=a.getGraphics();//设定MyCanvas用的Graphics
windowWidth=a.getSize().width;//窗口宽度
windowHeight=a.getSize().height;//窗口高度
createViewport(DefaultViewportMax);//创建视图
}

privatevoidcreateViewport(intmax)...{
currentViewport=0;//视图索引的初始值设定
viewportMax=max;//设定视图数的最大值
viewMinX=newdouble[viewportMax];//视图X轴的最小值数组
viewMaxX=newdouble[viewportMax];//视图X轴的最大值数组
viewMinY=newdouble[viewportMax];//视图Y轴的最小值数组
viewMaxY=newdouble[viewportMax];//视图Y轴的最大值数组
viewMinX[0]=viewMinY[0]=0.0;//视图的最小值为0
viewMaxX[0]=viewMaxY[0]=1.0;//视图的最大值为1
viewportNum=1;//视图的当前索引为1
}
//自定义坐标系的范围的设定

publicvoidsetMyWindow(doublex1,doublex2,doubley1,doubley2)...{
userMinX=x1;//窗口的X轴的最小值设定
userMaxX=x2;//窗口的X轴的最大值设定
userMinY=y1;//窗口的Y轴的最小值设定
userMaxY=y2;//窗口的Y轴的最大值设定
}
//视图的设定

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

/***//****视图的复位****/

publicvoidresetViewport()...{
currentViewport=0;//视图索引返回到0
viewMinX[0]=viewMinY[0]=0.0;//视图的最小值为0
viewMaxX[0]=viewMaxY[0]=1.0;//视图的最大值为1
viewportNum=1;//视图数为1
}

/***//****将视图坐标转换到javaAWT坐标方法***/

publicintgetIntX(doublex)...{
return(int)(windowWidth*x);
}//窗口宽度加倍

publicintgetIntY(doubley)...{
return(int)(windowHeight*(1-y));
}//窗口高度加倍

/***//*******将自定义坐标转换到视图坐标**********/

publicdoubleviewX(doublex)...{
doubles=(x-userMinX)/(userMaxX-userMinX);
doublet=viewMinX[currentViewport]+s*
(viewMaxX[currentViewport]-viewMinX[currentViewport]);
returnt;
}

publicdoubleviewY(doubley)...{
doubles=(y-userMinY)/(userMaxY-userMinY);
doublet=viewMinY[currentViewport]+s*
(viewMaxY[currentViewport]-viewMinY[currentViewport]);
returnt;
}

/***//*******将自定义坐标转换到javaAWT坐标********/

publicintgetX(doublex)...{
doublexx=viewX(x);//x转换到视图坐标
intix=getIntX(xx);//视图转换到java坐标
returnix;
}

publicintgetY(doubley)...{
doubleyy=viewY(y);//y转换到视图坐标
intiy=getIntY(yy);//视图转换到java坐标
returniy;
}

/***//******得到Dimension(维数)的方法**********/

publicintgetDimensionX(doublew)...{
doublex=viewMaxX[currentViewport]-viewMinX[currentViewport];
x*=windowWidth*w/(userMaxX-userMinX);
return((int)Math.abs(x));
}

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

/***//*****颜色设定方法******/

publicColorgetColor()...{returncurrentFrontColor;}//当前的颜色检索

publicvoidsetColor(Colorc)...{
myGraphics.setColor(c);
currentFrontColor=c;//当前颜色设定
}

publicColorgetForeground()...{returncurrentFrontColor;}//前面颜色检索

publicvoidsetForeground(Colorc)...{//前面颜色设定
myComponent.setForeground(c);
currentFrontColor=c;
}

publicColorgetBackground()...{returncurrentBackColor;}//背景颜色检索

publicvoidsetBackground(Colorc)...{
myComponent.setBackground(c);
currentBackColor=c;//背景颜色设定
}

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

publicvoiddrawLine(doublex1,doubley1,doublex2,doubley2)...{
//转换到java坐标系值
intix1=getX(x1);
intiy1=getY(y1);
intix2=getX(x2);
intiy2=getY(y2);
myGraphics.drawLine(ix1,iy1,ix2,iy2);
}

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

publicvoiddrawString(Stringstr,doublex,doubley)...{
intix=getX(x);//自定义坐标轴到java坐标轴
intiy=getY(y);//自定义坐标轴到java坐标轴
myGraphics.drawString(str,ix,iy);
}

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

publicvoidfillPolygon(double[]x,double[]y,intnumPoints)...{
int[]ix=newint[numPoints];
int[]iy=newint[numPoints];

for(inti=0;i<numPoints;i++)...{
ix[i]=getX(x[i]);//自定义坐标轴到java坐标轴
iy[i]=getY(y[i]);//自定义坐标轴到java坐标轴
}
myGraphics.fillPolygon(ix,iy,numPoints);
}
}
MyCoordinate.java(测试类)
//<appletcode=MyCoordinatewidth=300height=300>
//</applet>


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




publicclassMyCoordinateextendsApplet...{

MyCanvasm;//MyCanvas用数据
finalstaticintidealSizeX=600;
finalstaticintidealSizeY=350;

publicvoidinit()...{m=newMyCanvas(this);}//生成myCanvas对象

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

运行结果:

闪……