【Java案例】余弦函数
案例描述
在屏幕上画出余弦函数cos(x)曲线,如图1.6所示。
图1.6 余弦函数cos(x)曲线
案例分析
连续的曲线是由点组成的,点与点之间距离比较近,看上去就是曲线了,画图的关键是画出每个点。Java提供了三角函数方法,直接调用cos()方法就可以根据x坐标计算出y坐标。需要注意的是,cos()方法输入的参数是弧度值,要进行坐标转换,同样,得到的结果也要进行转换处理。从图1.6中可以看出,这条余弦曲线有两个周期,我们可以把x坐标控制在0~720。
案例实现
(1)确定程序架构
从图1.6中,我们可以发现,整个图形包括x轴、y轴及余弦曲线。控制台不方便输出图形,这里以Applet形式输出。这样我们就可以写出程序框架了,代码如下:
public class Ch1_3 extends Applet
{
int x,y;
public void start()
//当一个Applet被系统调用时,系统会自动调用 start()方法
{
Graphics g=getGraphics(); //画画之前,必须先取得画笔
//画x轴
//画y轴
//画cos(x)曲线
}
}
(2)画x轴
为了画出图1.6所示效果,我们可以把坐标原点设定为(360,200),x轴就是从左到右的很多点组成,通过循环语句很容易实现,代码如下:
for(x=0;x<=750;x+=1)
{
g.drawString("·",x,200); //画x轴
}
细心的读者会发现,x轴上还有个箭头,这个是如何实现的呢,其实很简单,是由两条线段交汇而成。为方便起见,两条线段都与x轴成45°角,很容易得到表达式的方程:y=x–550,y=950–x。代码如下:
for(x=740;x<=750;x+=1)
{
g.drawString("·",x,x-550); //x轴上方斜线
g.drawString("·",x,950-x); //x轴下方斜线
}
(3)画y轴
参考上面x轴的绘制,很容易画出y轴,代码如下:
//y轴
for(y=0;x<=385;y+=1)
{
g.drawString("·",360,y); //画y轴
}
//y轴箭头
for(x=360;x<=370;x+=1)
{
g.drawString("·",x-10,375-x);
g.drawString("·",x,x-355);
}
(4)画cox(x)曲线
图形的主体是cox(x)曲线,从图1.6中可以看出,这条余弦曲线有两个周期,我们可以把x坐标控制在0~720。cox(x)返回的结果小于1,为了看到图1.6效果,必须进行放大处理,这里放大了80倍,同时把图形向下平移了200个像素。代码如下:
//两个周期,即4Л
for(x=0;x<=720;x+=1)
{
a=Math.cos(x*Math. PI/180);
y=(int)(200+80*a); //放大80倍并向下平移200个像素
g.drawString("·",x,y);
}
(5)完整程序
现在我们就需要把刚才的程序进行组合,构成我们的完整程序:
import java.applet.*;
import java.awt.*;
public class Ch1_3_2 extends Applet
{
int x,y;
public void start()
{
//画画之前,必须先取得画笔
Graphics g=getGraphics();
//画x轴、y轴
for(x=0;x<=750;x+=1)
{
g.drawString("·",x,200);
if(x<=385) g.drawString("·",360,x);
}
g.drawString("Y",330,20);
//画y轴箭头
for(x=360;x<=370;x+=1)
{
g.drawString("·",x-10,375-x);
g.drawString("·",x,x-355);
}
//画x轴箭头
g.drawString("X",735,230);
for(x=740;x<=750;x+=1)
{
g.drawString("·",x,x-550);
g.drawString("·",x,950-x);
}
//画cox()曲线
for(x=0;x<=720;x+=1)
{
double a=Math.cos(x*Math. PI/180+Math.PI);
y=(int)(200+80*a); //放大80倍并向下平移200个像素
g.drawString("·",x,y);
}
}
}
(6)Ch_1网页代码:
<html>
<head><title>余弦曲线测试</title></head>
</body>
<p>
<!--调用Ch1_3字节码文件 -->
<applet code=Ch1_3.class
<!--设置窗口大小 -->
width=900
height=600>
</applet>
</body>
</html>
(7)运行结果
把Ch1_3.java文件编译后的Ch1_3.class文件放到Ch1_3.html网页同一目录下,直接用IE浏览器打开Ch1_3.html,运行程序,结果如图1.6所示。
扩展训练
前面介绍的余弦曲线的绘制,我们看到的是一个完整的静态图形,能否动态地展现绘制的过程?答案是肯定的,我们可以采用线程的方式来实现,参考代码如下:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
public class donghua_cos extends Applet implements Runnable
//通过实现Runnable接口实现线程操作
{
int x,y;
double a;
int xpos=0;
Thread runner;
boolean painted=false;
public void init() //Applet创建即启动执行,坐标初始化
{
// TODO Auto-generated method stub
Graphics g=getGraphics(); //画画之前,必须先取得画笔
for(x=0;x<=750;x+=1) //画x轴
{
g.drawString("·",x,200);
if(x<=385) g.drawString("·",360,x);
}
g.drawString("Y",330,20); //画y轴
for(x=360;x<=370;x+=1) //画y轴箭头
{
g.drawString("·",x-10,375-x);
g.drawString("·",x,x-355);
}
g.drawString("X",735,230);
for(x=740;x<=750;x+=1) //画x轴箭头
{
g.drawString("·",x,x-550);
g.drawString("·",x,950-x);
}
}
public void start() //Applet创建后自启动方法
{
// TODO Auto-generated method stub
if(runner==null){
runner=new Thread(this); //通过Thread类来启动Runnable
runner.start(); //线程启动
}
}
public void stop() //Applet生命周期结束后自启动方法
{
// TODO Auto-generated method stub
if(runner!=null){
runner=null; //结束线程
}
}
public void run() //线程运行方法
{
// TODO Auto-generated method stub
while(true){
for(xpos=0;xpos<900-90;xpos+=3)
//循环设置曲线x轴坐标边界
{
repaint(); //调用paint()方法
try{
Thread.sleep(100); //线程休息100毫秒
}catch(InterruptedException e){}
if(painted)
{
painted=false;
}
}
}
}
public void paint(Graphics g) //画图方法
{
for(x=0;x<=xpos;x+=1) //循环画曲线
{
a=Math.cos(x*Math. PI/180+Math.PI);
y=(int)(200+80*a); //放大80倍并向下平移200个像素
g.drawString("·",x,y);
}
painted=true;
}
- Python数据增强(data augmentation)库--Augmentor 使用介绍
- Leetcode-Easy 101. Symmetric Tree
- 数据结构-栈的定义及python实现
- 【关关的刷题日记59】Leetcode 257 Binary Tree Paths
- 学大伟业 国庆Day2
- ECMAScript 6入门 - 变量的解构赋值
- 二叉排序树 python实现
- ES6新特性概览
- 数据结构-顺序表的定义及python实现
- 洛谷P1516 青蛙的约会
- python实现二叉树的创建和遍历
- python中numpy模块下的np.clip()的用法
- Leetcode-Easy 543. Diameter of Binary Tree
- Leetcode-Easy 572. Subtree of Another Tree
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- linux(ubuntu)用户连续N次输入错误密码进行登陆时自动锁定X分钟
- linux下安装golang的方法
- Linux系统的文件传输方法
- CentOS 6.8 NFS 文件共享设置的方法
- linux如何mount挂载磁盘并设置开机自动mount的实现
- 浅谈Linux的编码及编码转换方法
- 在 Linux 上用 DNS 实现简单的负载均衡的方法
- centos7.2.1511安装jdk1.8.0_151及mysql5.6.38的方法
- Linux CentOS使用crontab设置定时重启的方法
- centos安装php5、卸载php、安装php7的教程
- centos7中crontab定时计划任务5分钟一次命令写法
- Ubuntu16.04 安装Teamviewer的教程详解
- 01 . OpenResty简介部署,优缺点,压测,适用场景及用Lua实现服务灰度发布
- 详解Linux iptables 命令
- 详解fedora 开启 apache 并 开启目录浏览模式