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