基于Java的簡(jiǎn)易函數(shù)圖像繪制程序設(shè)計(jì)

[日期:2024-04-15] 作者:信息技術(shù) 次瀏覽 [字體: ]

基于Java的簡(jiǎn)易函數(shù)圖像繪制程序設(shè)計(jì)

2024屆5班 史哲予

     程序設(shè)計(jì)就像一扇充滿魔力的大門,只需要一把鑰匙,你就可以創(chuàng)造一個(gè)屬于自己的世界。而這扇門的鑰匙就是一門可以與電腦對(duì)話的程序設(shè)計(jì)語(yǔ)言。對(duì)我而言,程序設(shè)計(jì)最大的魅力在于無(wú)論是使用電腦時(shí)的個(gè)性化需求,或是日常學(xué)習(xí)中所涉及的知識(shí)點(diǎn),它都可以與之完美契合!而當(dāng)程序在你眼前完美運(yùn)行時(shí),你的愉悅之情也是難以替代的。于是,設(shè)計(jì)編寫各種有趣實(shí)用的程序成為了我的興趣之一。

Java當(dāng)前最流行的程序設(shè)計(jì)語(yǔ)言之一。它的特點(diǎn)顯而易見:簡(jiǎn)單、面向?qū)ο蟆踩?、高性能以及跨平臺(tái)等。它可以在各種電腦、手機(jī)、移動(dòng)設(shè)備、終端,以及各種操作系統(tǒng)上成功運(yùn)行。憑借著現(xiàn)代信息技術(shù)的飛速發(fā)展,Java被大范圍地使用。大型應(yīng)用程序、Web及服務(wù)器后臺(tái)處理、大數(shù)據(jù)技術(shù)、集成開發(fā)工具等都由它開發(fā)。在尖端領(lǐng)域,Java造就了Maestro火星探測(cè)器控制器、世界上最快的圖形分析引擎之一(PGX)以及耗資30億美元的集成基因組瀏覽器(IGB)。當(dāng)然,還有最受歡迎的游戲Minecraft。

有了這樣一個(gè)強(qiáng)大的程序開發(fā)設(shè)計(jì)平臺(tái),我們就可以開啟今天的函數(shù)圖像可視化進(jìn)程了。函數(shù)通常由兩個(gè)變量(Variable)組成,自變量(Argument)和因變量(Dependent variable)。如:y=x,表示了因變量與自變量的“相等關(guān)系”。各個(gè)自變量都有對(duì)應(yīng)的因變量。函數(shù)圖像(Function image)即是以xy為坐標(biāo)的點(diǎn)在平面直角坐標(biāo)系中組成的圖像。數(shù)學(xué)課上,函數(shù)圖像的繪制只需三步:列表、描點(diǎn)、連接。使用同樣的方式在電腦上更能輕而易舉地實(shí)現(xiàn)。只需要確定三個(gè)因素:解析式、自變量的取值范圍以及步長(zhǎng)。通過(guò)循環(huán)結(jié)構(gòu)繪制圖像即可。接下來(lái)我們就來(lái)進(jìn)行算法分析…...

首先,我們需要以窗口幾何中心為原點(diǎn),向右、上方為正方向建立一個(gè)直角坐標(biāo)系。接下來(lái),通過(guò)循環(huán)繪制,需要在程序里創(chuàng)建四個(gè)變量:xoyo,xy。這些變量分別表示初始xy值,改變后的xy值。它們可以組成兩組坐標(biāo),兩組坐標(biāo)用線段來(lái)連接就構(gòu)成了一段函數(shù)圖像。其中,xox是隨著循環(huán)直接變化的變量,xo的初值默認(rèn)為-10800,而x則是xo按單位步長(zhǎng)Δx自增后的值。即:x = xo + Δx (Δx>0)。

xx、oyyo是函數(shù)圖像坐標(biāo)系對(duì)應(yīng)計(jì)算機(jī)窗口坐標(biāo)系的偏移值。由于在Java繪圖中,窗口的坐標(biāo)系是以左上角為原點(diǎn),向右、下方為正方向,而數(shù)學(xué)中函數(shù)的坐標(biāo)都是相對(duì)于原點(diǎn)即窗口中心的,而且以右、上為正方向。因此,這里我們要使用ORIGIN_XORIGIN_Y兩個(gè)常量(Const)對(duì)坐標(biāo)系的偏移量進(jìn)行修正,將函數(shù)圖像坐標(biāo)系映射到計(jì)算機(jī)窗口坐標(biāo)系中。

xo初始化為最小,即-10800,并計(jì)算出yo。然后在自變量的取值范圍內(nèi),從小到大以最小單位長(zhǎng)度為步長(zhǎng)列舉x,計(jì)算出y。以(xo,yo)(x,y)畫線段,完成后將xo,yo的值分別用xy替代,進(jìn)入下一次迭代,思路如圖所示。

   

接下來(lái)開始代碼編寫。我所使用的是IntelliJ IDEA來(lái)進(jìn)行開發(fā),配置環(huán)境為JDK 11.0.12。按照慣例配置好開發(fā)環(huán)境項(xiàng)目結(jié)構(gòu)等。首先,要顯示出圖像,窗口是必備的。Java提供了JFrame類,創(chuàng)建自己的窗口就需要繼承自JFrame,也就是將自己的類作為一個(gè)擁有JFrame所有功能和屬性的對(duì)象。然后聲明窗口寬和高,并重寫(Override)JFrame提供的paint方法以繪制函數(shù)圖像。

現(xiàn)在我們已經(jīng)擁有了自己的窗口,我們可以在對(duì)窗口進(jìn)行優(yōu)化。直角坐標(biāo)系的繪制可以分為三步:找到原點(diǎn)并畫出坐標(biāo)軸、畫出標(biāo)尺、畫出格子。全部都可以通過(guò)調(diào)用drawLine方法畫直線完成。原點(diǎn)坐標(biāo)即(W/2,H/2),而坐標(biāo)軸即畫直線y = H/2 x = W/2,標(biāo)尺則可以用給定長(zhǎng)度(如40px)在對(duì)應(yīng)位置畫線段來(lái)實(shí)現(xiàn)。但是這兩步要等到最后做,必須要先畫格子,這樣才不會(huì)不會(huì)把坐標(biāo)軸遮住。為了不干擾坐標(biāo)軸和函數(shù)圖像,格子可以更改為淺一點(diǎn)的顏色,同時(shí),與標(biāo)尺重合畫出坐標(biāo)軸的刻度。(還可以加粗顯示特定邊)

現(xiàn)在窗口已經(jīng)完工。但是運(yùn)行程序需要一個(gè)main方法,也就是主線程(Main Thread)。我們直接在下面創(chuàng)建main方法,先生成窗口對(duì)象,然后設(shè)置大小、位置、可見性等屬性值,然后運(yùn)行。一個(gè)簡(jiǎn)單的直角坐標(biāo)系就這樣完成了!

接下來(lái)是實(shí)現(xiàn)任意函數(shù)圖像的繪制。在paint方法中使用一個(gè)循環(huán),循環(huán)參數(shù)i的初始值設(shè)置為-10800。在i10800時(shí),i循環(huán)每執(zhí)行一次,i都要自增,然后按相應(yīng)函數(shù)表達(dá)式進(jìn)行運(yùn)算、繪圖。

最大的難點(diǎn)在于步長(zhǎng)。在Java繪圖中,各個(gè)點(diǎn)的坐標(biāo)只能為整數(shù)(Integer)。步長(zhǎng)被限制在一個(gè)像素(1px)以外,導(dǎo)致曲線太不精確,弧度太大就會(huì)變成一個(gè)個(gè)鋸齒狀的“臺(tái)階”。但實(shí)際上我們可以利用編程語(yǔ)言的不同的變量類型來(lái)巧妙解決這個(gè)問(wèn)題。當(dāng)你給一個(gè)int變量賦值為小數(shù)時(shí),Java會(huì)自動(dòng)將這個(gè)值取整。在這一點(diǎn)的幫助下,我們可以在一開始就定義一個(gè)小數(shù)變量arc來(lái)表示自變量。每一次循環(huán)開始,arc賦值為PI×i÷360。注意,這里的PI只是為了讓i的值自動(dòng)轉(zhuǎn)化為更小的雙精度小數(shù)類型(Double)。理論上,“360”替換成更大的數(shù),繪圖的精度也就會(huì)越高。但由于i的取值范圍不會(huì)變,所以,把360改成更大的數(shù)反而會(huì)讓電腦不堪重負(fù),并且只畫出小部分圖像,一味追求高精度并沒(méi)有多大實(shí)際意義。      

到現(xiàn)在,我們的函數(shù)繪制已經(jīng)完成了。但是我們可以發(fā)現(xiàn),由于我們進(jìn)行了奇幻的操作,函數(shù)畫出來(lái)的圖像很小。所以需要加上一個(gè)小變量:

private static int SCALE_X = 40;  private static int SCALE_Y = 40;)由它們來(lái)控制圖像的縮放。這就像一次函數(shù)中的k值一樣,直接在arcxy的值轉(zhuǎn)換前先將×進(jìn)行適當(dāng)?shù)目s放就行了。核心代碼及繪制的正弦函數(shù)圖像如下。