t+=deltat;
x=fx(t);y=fy(t);
m.lineTo(x,y);//画直线到该点
}
m.lineTo(x0,y0);//画直线到起点,结束
}//描绘方法paint结束
}//参数曲线描绘类结束
(2)package实验4;
//explicitCurve.java
//显式曲线描绘程序
importjava.awt.*;//绘图基于javaAWT包
importjava.applet.Applet;
//定义显式曲线描绘类
publicclassexplicitCurveextendsApplet{
MyCanvasm;//定义MyCanvas的对象
privatedoublexmin=-4;//x轴的最小值
privatedoubleymin=-4;//y轴的最小值
privatedoublexmax=4;//x轴的最大值
privatedoubleymax=4;//y轴的最大值
privatedoublegDelta=0.10;//坐标轴刻度间距
//Applet程序的自动初始化方法init
publicvoidinit(){
setSize(500,500);
m=newMyCanvas(this);//生成MyCanvas类的对象
}
//描绘曲线y=x^3-1
privatedoublef(doublex){
returnx*x*x-1;
}
//Applet程序的描绘方法paint
publicvoidpaint(Graphicsg){
m.setBackground(Color.gray);//背景色
m.setColor(Color.blue);//前景色
m.setWindow(xmin,xmax,ymin,ymax);//用户坐标系范围
//缺省的视图为m.setViewport(0,1,0,1)和JavaAWT窗口大小一样
m.drawLine(xmin,0,xmax,0);//画x轴及刻度线
for(inti=(int)xmin;i<=(int)xmax;i++){
m.drawLine((double)i,-gDelta,(double)i,gDelta);
m.drawString(String.valueOf(i),i-gDelta,-0.4);
}
m.drawLine(0,ymin,0,ymax);//画y轴及刻度线
for(intj=(int)ymin;j<=(int)ymax;j++){
m.drawLine(-gDelta,(double)j,gDelta,(double)j);
m.drawString(String.valueOf(j),-0.4,j-gDelta);
}
/*画曲线*/
doublex=-2.0;//曲线的起始点
doubley=f(x);
m.moveTo(x,y);//抬笔移动到xy点处
doubledeltaX=0.05;//x的步长
for(inti=0;i<80;i++){//x方向走80步
x+=deltaX;y=f(x);
m.lineTo(x,y);//落笔画直线到xy点处
}
}//描绘方法paint结束
}//显式曲线描绘类结束
(3)package实验4;
//Java图形学之贝赛尔曲线Application程序
//贝塞尔曲线是依据四个位置任意的点坐标绘制出的一条光滑曲线。
//本程序直接在JAVAAWT坐标系下绘图(没有用户坐标系和视图)
//考试内容1:
利用MyCanvas包,加上用户坐标系,四个点的坐标为用户坐标系
//考试内容2:
把n个点用贝塞尔曲线分段连接为一条光滑曲线
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
//贝赛尔曲线类
publicclassBezierLineextendsFrame//继承窗体
implementsActionListener,ComponentListener{//接口
privateButtonbutton_start,button_close;//两个按钮
//内部类定义节点类
protectedclassNodeextendsObject{
protectedintx,y;
protectedNode(){//构造1
this.x=0;
this.y=0;
}
protectedNode(intx,inty){//构造2
this.x=x;
this.y=y;
}
}//结束内部节点类
privateNodep[]=newNode[4];//塞尔曲线4个节点
//贝赛尔曲线类构造方法
publicBezierLine(){
super("Bezier曲线");//调用父类Frame的构造方法,显示窗口标题
this.setSize(500,500);
this.setLayout(newFlowLayout());
button_start=newButton("划线");
button_start.addActionListener(this);
button_close=newButton("关闭");
button_close.addActionListener(this);
//测试数据:
4个节点赋值
/*p[0]=newNode(50,150);
p[1]=newNode(100,250);
p[2]=newNode(150,300);
p[3]=newNode(200,350);*/
/*p[0]=newNode(100,200);
p[1]=newNode(200,100);
p[2]=newNode(300,200);
p[3]=newNode(200,300);*/
p[0]=newNode(100,260);
p[1]=newNode(150,150);
p[2]=newNode(250,120);
p[3]=newNode(330,250);
this.add(button_start);
this.add(button_close);
this.setVisible(true);//显示窗口和界面
}//结束贝赛尔曲线类构造方法
//辅助函数:
求t的i次方
publicdoublepow(doublet,inti){
if(t==0&&i==0)return1;
elsereturnMath.pow(t,i);
}
//辅助函数:
递归求n的阶乘
publicintfactorial(intn){
if(n==0||n==1)return1;
elsereturnn*factorial(n-1);
}
//定义Beinstein函数
publicdoubleBin(intn,inti,doublet){
doubletm;
tm=factorial(n)/(factorial(i)*factorial(n-i))*pow(t,i)*pow(1-t,n-i);
returntm;
}
//定义paint函数
publicvoidpaint(Graphicsg){
inti,j,n,x1=0,y1=0,x0,y0;
doublet;
n=4;//贝赛尔4个节点
g.setColor(Color.red);
g.fillOval(p[0].x-5,p[0].y-5,10,10);//实心圆
for(j=1;jg.fillOval(p[j].x-5,p[j].y-5,10,10);
g.drawLine(p[j-1].x-1,p[j-1].y-1,p[j].x-1,p[j].y-1);
}
x0=p[0].x;//起点
y0=p[0].y;
g.setColor(Color.blue);
for(t=0;t<=1;t+=0.01){//参数法求点坐标
for(i=0;ix1=x1+(int)(Bin(n-1,i,t)*p[i].x);
y1=y1+(int)(Bin(n-1,i,t)*p[i].y);
}//i循环
g.drawLine(x0,y0,x1,y1);//划短直线
x0=x1;//下一折线
y0=y1;
x1=0;
y1=0;
}//参数t循环
}
//定义按钮事件响应函数
publicvoidactionPerformed(ActionEvente){
if(e.getSource()==button_start)
repaint();//调用paint()绘图
if(e.getSource()==button_close)
System.exit(0);//结束
}
//窗口缩放事件
publicvoidcomponentResized(ComponentEvente){
repaint();
}
//其它事件响应虚函数
publicvoidcomponentMoved(ComponentEvente){}
publicvoidcomponentHidden(ComponentEvente){}
publicvoidcomponentShown(ComponentEvente){}
//========主方法========
publicstaticvoidmain(Stringarg[]){
BezierLinebl=newBezierLine();//定义对象
/*激活构造方法*/
}
}//结束贝赛尔曲线类
运行结果:
(给出运行结果的截屏和说明)
(1)
(2)
(3)
实验体会:
(简单说明学习到的知识点和收获)
1.学习了圆的曲线的画法
2.学习了数学曲线的画法,他是递推的一种方式来完成,不同的是他的步长可以由用户设置
3.学习了贝塞尔曲线的画法
4.巩固了以前学习的画坐标,直线的方法