MyPointp1=pointlist.get(i);
intx1=p1.getX();
inty1=p1.getY();
MyPointp2=pointlist.get(i-1);
intx2=p2.getX();
inty2=p2.getY();
g.drawLine(x1,y1,x2,y2);
}
}
三角形的缩小变换:
privatevoidchangePictureSize(MyPointunchangedpoint,doublesx,doublesy){
for(MyPointpb:
pointlist){
pb.setX((int)(pb.getX()*sx+unchangedpoint.getX()*(1-sx)));
pb.setY((int)(pb.getY()*sy+unchangedpoint.getY()*(1-sy)));
}
g.setColor(Color.BLUE);
drawPicture
(1);
}
三角形关于特定直线的对称变换:
privatevoidchangePictureLocation(){
for(MyPointpb:
pointlist){
doublex1=(pb.getY()+2*pb.getX()+0.75)/2.5;
doubley1=(pb.getY()+2*pb.getX()-3)/5.0;
pb.setX((int)(x1+(x1-pb.getX())));
pb.setY((int)(y1-(pb.getY()-y1)));
}
g.setColor(Color.BLUE);
drawPicture
(1);
}
四边形的旋转变换:
四边形点的录入和绘画同三角形
四边形的旋转函数显示如下:
privatevoidspinPicture(){
doubler;
r=15/180.0*3.1415926;//旋转150
for(MyPointpb:
pointlist2){//遍历多边形的顶点
doublex1=pb.getX()*Math.cos(r)-pb.getY()*Math.sin(r);//根据度数和顶点值来确定改变的顶点
doubley1=pb.getX()*Math.sin(r)+pb.getY()*Math.cos(r);
pb.setX((int)(x1));
pb.setY((int)(y1));
}
g.setColor(Color.ORANGE);
drawPicture
(2);
}
键盘的监听类:
classKeyMonitorextendsKeyAdapter{
publicvoidkeyPressed(KeyEvente){
switch(e.getKeyCode()){
caseKeyEvent.VK_C:
//清空画布
panel.repaint();
break;
caseKeyEvent.VK_1:
//准备进行三角形的变换
putPoint1();
g.setColor(Color.RED);
drawPicture
(1);
g.drawLine(0,0,0,600);
g.drawLine(0,0,600,0);
g.drawLine(-30,(int)(-63/4),200,(int)(397/4));
break;
caseKeyEvent.VK_2:
//准备进行四边形的变换
putPoint2();
g.setColor(Color.MAGENTA);
drawPicture
(2);
g.drawLine(0,0,0,600);
g.drawLine(0,0,600,0);
break;
caseKeyEvent.VK_3:
BasicConstructbc=newBasicConstruct();
bc.addMyBox(x,y,z,bc);
break;
caseKeyEvent.VK_S:
//图形的缩小变换
changePictureSize(pointlist.get(0),0.5,0.5);
break;
caseKeyEvent.VK_L:
//图形的对称变换
changePictureLocation();
break;
caseKeyEvent.VK_T:
//四边形的旋转变换
spinPicture();
break;
caseKeyEvent.VK_E:
//复原3D图形
x=0.1f;
y=0.1f;
z=0.1f;
break;
caseKeyEvent.VK_X:
//X轴的错切变换
BasicConstructbc0=newBasicConstruct();
x=x+0.1f;//x轴错切,改变x轴的比例,
bc0.addMyBox(x,y,z,bc0);//长方体的绘制函数
break;
caseKeyEvent.VK_Y:
//Y轴的错切变换
BasicConstructbc1=newBasicConstruct();
y=y+0.1f;//y轴错切,改变y轴的比例,
bc1.addMyBox(x,y,z,bc1);
break;
caseKeyEvent.VK_Z:
//Z轴的错切变换
BasicConstructbc2=newBasicConstruct();
z=z+0.1f;//z轴错切,改变z轴的比例,
bc2.addMyBox(x,y,z,bc2);
break;
default:
;
}
}
}
3D图形的框架搭建
/*
*绘制三维图形的类
*里面包含了绘制长方体的方法和鼠标的监听事件
*/
publicclassBasicConstructextendsJFrame{
protectedSimpleUniversesimpleU;
protectedBranchGrouprootBranchGroup;
publicBasicConstruct(){
initial_setup();
}
/*
*初始化步骤
*/
protectedvoidinitial_setup(){
getContentPane().setLayout(newBorderLayout());//得到框架和设置布局
GraphicsConfigurationconfig=SimpleUniverse
.getPreferredConfiguration();//得到配置函数
Canvas3Dcanvas3D=newCanvas3D(config);//创建3d图形的面板
getContentPane().add("Center",canvas3D);//把3d图形面板添加到框架上
simpleU=newSimpleUniverse(canvas3D);//设置3d图形的画布形式
rootBranchGroup=newBranchGroup();
}
/*
*设置3d画布的视角以及高光等参数
*/
publicvoidaddDirectionalLight(Vector3fdirection,Color3fcolor){
BoundingSpherebounds=newBoundingSphere();
bounds.setRadius(1000d);
DirectionalLightlightD=newDirectionalLight(color,direction);
lightD.setInfluencingBounds(bounds);
rootBranchGroup.addChild(lightD);
}
/*
*本次实验的核心函数创建长方体的函数需要长方体的长宽高比例以及颜色
*/
publicvoidaddBox(floatx,floaty,floatz,Color3fdiffuse,Color3fspec){
Appearanceapp=newAppearance();//设置长方体的视角以及绘制参数
Materialmat=newMaterial();//创建节点
mat.setDiffuseColor(diffuse);//设置长方体的轮廓颜色和表面颜色
mat.setSpecularColor(spec);
mat.setShininess(5.0f);//超出范围则不显示
app.setMaterial(mat);
Boxbox=newBox(x,y,z,app);//创建长方体
TransformGrouptg=newTransformGroup();
tg.addChild(box);
rootBranchGroup.addChild(tg);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
/*
*创建鼠标事件,使长方体能够被移动和旋转
*/
MouseRotatemyMouseRotate=newMouseRotate();
myMouseRotate.setTransformGroup(tg);
myMouseRotate.setSchedulingBounds(newBoundingSphere());
rootBranchGroup.addChild(myMouseRotate);
MouseTranslatemyMouseTranslate=newMouseTranslate();
myMouseTranslate.setTransformGroup(tg);
myMouseTranslate.setSchedulingBounds(newBoundingSphere());
rootBranchGroup.addChild(myMouseTranslate);
MouseZoommyMouseZoom=newMouseZoom();
myMouseZoom.setTransformGroup(tg);
myMouseZoom.setSchedulingBounds(newBoundingSphere());
rootBranchGroup.addChild(myMouseZoom);
}
publicvoidfinalise(){
simpleU.addBranchGraph(rootBranchGroup);
simpleU.getViewingPlatform().setNominalViewingTransform();
}
/*
*封装类需要调用的函数,主要是整合3d长方体的创建
*/
publicvoidaddMyBox(floatx,floaty,floatz,BasicConstructbc){
bc.setSize(1024,768);
bc.addBox(x,y,z,newColor3f(1,0,0),newColor3f(1,0,0));
bc.addDirectionalLight(newVector3f(0f,0f,-1),
newColor3f(1f,1f,0f));
bc.finalise();
bc.show();
return;
}
}
实验结果
本次实验中图形的变换可以通过键盘来控制。
1、运行程序之后,点击“1”进入三角形的变换:
2、点击“S”进行三角形的缩小变换:
如上图所示,蓝色的三角形为原三角形缩小后的三角形。
3、点击“L”键,进行三角形关于直线-2x+4y+3=0的对称变换:
如图所示,直线上方的三角形即为关于直线对称后得到的三角形。
4、点击“C”键,清空画布,进行四边形的变换:
5、点击“2”键,进行四边形的变换:
6、点击“T”键,进行四边形的旋转变换,旋转角度为15度:
7、点击“3”查看java3D的立方体:
用鼠标拖动即可对立方体进行旋转,查看其3D视图:
8、点击“X”键,对立方体进行X轴方向的错切:
9、点击“Y”键,对立方体进行Y轴方向的错切:
10、点击“Z”键,对立方体进行Z轴方向的错切:
实验总结
本次实验让我了解并掌握了图形的基本几何变换,对于本次实验,有如下说明:
1、本次实验继承了JFrame,并在程序中使用了JPanel,使得画笔的获得更为方便,可直接在函数中调用声明为成员变量的画笔,从而避免了作为参数传递的麻烦。
2、本次实验中运用了tanslate(intx,inty)函数,将图形上下文的点平移到当前坐标系中的点(x, y)。
便于实验结果的观察。
本次实验的不足在于:
改变大小的函数,对称变换的函数以及旋转变换的函数中均存在对double类型数的取整运算,使得实验结果存在必然的误差,在改变大小以及对称变换中体现的不明显,但是在旋转变换中误差很明显:
在旋转一周多时图形显示如下:
由上图可以看出图形变小了。
旋转多周后效果更为明显:
给要进行取整运算的表达式加上0.5,这个问题仍然存在,这个旋转问题在本次实验中还没有找到更好的解决办法,希望在今后的学习中可以得到解决。
指导教师意见
签名:
年月日