【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;
 }

原文发布于微信公众号 - Java帮帮(javahelp)

原文发表时间:2018-03-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏听雨堂

从MapX到MapXtreme2004[6]-标点心得

在Web上标点,首先要将图层所在文件夹的写权限放开。如果是普通的标点,可以这样:    MapInfo.Data.Table tb=MapInfo.Engine...

22080
来自专栏hbbliyong

使用WPF教你一步一步实现连连看(三)

这次首先对以前的结构进行了调整: 第一步:把MyButton按钮的属性独立成一个类,放在一个单独的MyButton.cs中,把图片的初始化也放到里面。 调整代...

35770
来自专栏图像识别与深度学习

2018-06-30 详解 MNIST 数据集

15220
来自专栏深度学习之tensorflow实战篇

网页爬虫-R语言实现基本函数

#*************网页爬虫-R语言实现,函数库文件*******# #****作者:H********************************...

32770
来自专栏逍遥剑客的游戏开发

Nebula3绘制2D纹理

16660
来自专栏mySoul

SVG绘制饼状图

25820
来自专栏GIS讲堂

说说地图中的聚类

虽然Openlayers4会有自带的聚类效果,但是有些时候是不能满足我们的业务场景的,本文结合一些业务场景,讲讲地图中的聚类展示。

13730
来自专栏小文博客

蓝桥杯 C语言省赛 习题2 格子中输出

17140
来自专栏算法channel

玩转Pandas,让数据处理更easy系列2

上一篇总结了Pandas中最重要的两个数据结构:Series和DataFrame,前者相当于更加强大的一维数组,是数组和字典的组合,因为既可以按照位置,也能通过...

10830
来自专栏落影的专栏

Metal入门教程总结

本文介绍Metal和Metal Shader Language,以及Metal和OpenGL ES的差异性,也是实现入门教程的心得总结。

1.2K60

扫码关注云+社区

领取腾讯云代金券