2024年11月14日 星期四

我們以數學技術為這個世界扭製出美麗的圖譜

我們以數學技術為這個世界扭製出美麗的圖譜


曾慶潭 Ching-Tang Tseng
ilikeforth@gmail.com
Hamilton, New Zealand
15 November 2024


1. 前言

這本是一篇於 20130416 曾經刊登於 https://how-are-we.webnode.tw/ 網頁的網文。

本人珍惜自己的創作,多年之後的今天,特將此文彙整、集中再刊出於此網頁,以利查找。

文內敘述是標準之繪出平面極座標函數與平面參數方程式函數圖形的方法,程式設計時就根據此方法繪圖。

原文的圖示以淺黃色繪製座標圈,視覺上很不明顯。程式略施修改,改採淺綠色繪製座標圈,效果就明顯的不同。

本文與原文的不同處,是此處刊出了繪圖的源程式。這裡才談 Forth ,程式只適合在這裡刊出。這種大型程式,很難在他處獲得,想詳細了解程式內容則需要下點功夫,程式不容易設計、也不容易用來教會新手使用,繪圖原理不變,才是主要重點。今早貼文前,我試 run 了這個 11 年前設計的程式,照樣能一鍵一圖,效果比當年只能在 XP 作業系統中執行時的效果好太多了。請注意!程式中欲繪之圖的數學函數,只須一列標準的數學表示式便能完成設計,它是 ABC Forth 的特色。程式中一口氣提供了 20 個簡單的範例函數式,想用就這樣用。成品圖包含了徑長的刻度數字,程式展示了圖文並茂的繪製方法。

我所使用的背景系統是這樣的:

Ubuntu 20.04 OS,
加裝視窗模擬軟體 wine 後,
直接執行 ABC660forthV61505.exe,
載入此繪圖程式後,壓下 F2 鍵,
就得到了繪製結果。

Linux 作業系統能夠立即擷圖,只須壓下 shift-print 雙鍵,然後操作滑鼠,框住擷圖區域,就能得到下列圖形:


2. 繪圖原理

描述變數間關係的數學式子稱為函數。


2-1. 平面極座標函數(Polar Function)

極座標函數是一種專門用來描述徑長(r)隨角度(θ)變化的數學式子。人們常因打字不便,而將希臘字母『θ』(讀作theta)改以 t 來取代。

一個最簡單的極座標函數,可以是 r = t 。

進一步,以常用三角函數變化,可以是 r = sin ( t ) ,我們就稱其為:以數學技術扭製出了一個新的數學函數。

更進一步,再以四則運算配合其它各種數學基本函數,更可以扭製出千千萬萬種 r 隨 t 而變化的數學式子。

我們利用扭製出來的數學式子,在以極座標表示的平面上繪圖,就能繪製出各種圖譜,其中,有許多圖譜具有奇特或美麗的花樣。

通常,極座標製圖時,都以右向的水平橫軸,作為角度為 0 的起始基準角度,以其計算出對應的函數徑長值後,在座標圖上繪製出起始之點。隨後,以逆時鐘旋轉方向,依序每次增加一個定量之角度,再根據同一數學函數,依次計算出各個對應的徑長值。將這一序列的極座標數據組,以打點方式標示,或以連線串接起來,直到計算並繪製至完成一圈 360 度時為止,就能獲得相應於極座標函數之完整的圖譜。

圖譜是千變萬化的,所以,您能創作,您能拿產品去小畫家中自行彩繪。

繪製完成的視窗圖中:

(1) 輔以座標及其刻度
(2) 列示單一刻度的對應數值
(3) 列示繪圖所根據的數學函數式子

適合供作學術性方面使用。我們也能提供不帶視窗窗框的無邊顯示圖,更適合在學術論文中使用。另有自定需求者,可以將圖檔輕易載入小畫家系統中,自行補白或美化。

直角座標與極座標線,分別以不同的顏色標示於圖中時,可以增加讀圖時對函數曲線變化的趨勢感,是否顯示這一部份?可以自由選定。

函數曲線比座標線來得重要,因此,我們強調以採用『多隻繪圖筆原理』的繪圖方式製圖。

函數曲線的顯示,可以選擇自己希望的顏色,函數曲線的繪製,也可選用以點狀、細連線、或粗彩線三種不同方式來繪製。


2-2. 平面參數方程式函數(Parametric Equation Function)

參數方程式函數的數學表示方式,與極座標函數不同,製圖方法也有所不同。

參數方程式函數曲線,使用直角座標來繪圖。

參數方程式函數,直接以下列方式表示 x 及 y 所有座標點的變化趨勢:

x = f(t)
y = g(t)

其中 x 與 y 均只單純的隨著另外一個 t 參數而變化,而由 t 所形成的函數,也是無限多種,因此,可繪之圖就能千變萬化。

參數方程式函數中的 t 變數,不適合將其想像成角度從 0 度變化到 360 度的對應關係,比較適合將其想像成是 x 與 y 的座標值是隨時間 t(time) 而變化的趨勢, t 可以是過去(負值)、現在(0值)、與未來(正值)的時間變化。

相對於極座標函數繪圖而言,參數方程式函數繪圖方式的主要不同之處,為函數繪圖時必須另行採用定義域來製圖。

極座標製圖時,函數的定義域為固定的,也就是 t(theta) 從 0 度變化到 360 度,便足以明確顯示函數曲線之變化趨勢。

以參數方程式函數繪圖時,其 t(time) 的定義域,則必須在繪出圖形之前先行選定,選定的範圍沒有限制,可以從很大的負值到很大的正值,選定之 t 的定義域範圍,會決定圖示的品質。

3. Win32Forth 附加 ABC Forth 功能後設計出來之源程式


 
\ Copyright (C) 2013 Ching-Tang Tseng

include winplot.f

\ ---------------------------------------------------------------------

\ 設定整個畫面底色的方法20140325

: SetBkColor ( cilor-obj -- )
  >R
  0 0 screen-width screen-height R> FillArea: demo-dc ;
\ Polar plot

: SetWhiteBG ( -- )
  White SetBkColor
;

\ ---------------------------------------------------------------------

500 to screen-width
560 to screen-height

\ ---------------------------------------------------------------------

\ 令WINPLOT主程式中具有八個單按鍵功能的向量式設計。

DEFER PLOT2
DEFER PLOT3
DEFER PLOT4
DEFER PLOT5
DEFER PLOT6
DEFER PLOT7
DEFER PLOT8
DEFER PLOT9

\ 先讓function key的功能生效,故預先進行下列設定,且不影響後續程式的規劃。

' noop IS PLOT2
' noop IS PLOT3
' noop IS PLOT4
' noop IS PLOT5
' noop IS PLOT6
' noop IS PLOT7
' noop IS PLOT8
' noop IS PLOT9

: Frame
  LTBLUE LINE-COLOR
              0             0 MOVETO
              0 screen-height LINETO
   screen-width screen-height LINETO
   screen-width             0 LINETO
              0             0 LINETO
;

' Frame IS PLOT9

\ -------------------------------------------------------------------

3 INTEGERS I XI YI
6 REALS r Rmax degree t X Y

10000 VALUE N

N ARRAY RR
N ARRAY XX
N ARRAY YY

: r(t) ( -- )
\ {{ r = 1.2345E23 * degree * cos ( 6 * t ) }} ; \ (1)花瓣逐漸縮小圖
\  {{ r = cos ( t ) }} ;                         \ (2)右圓圈圖
\  {{ r = exp ( -1.2 * t ) }} ;                  \ (3)飛機翅膀橫截面圖
\  {{ r = t }} ;                                 \ (4)螺旋線圖
  {{ r = sin ( 4 * t ) * cos ( 8 * t ) }} ;      \ (5)花辦圖
\  {{ r = 2 * ( 1 - cos ( t ) ) }} ;             \ (6)左心形圖
\  {{ r = 2 * ( 1 + cos ( t ) ) }} ;             \ (7)右心形圖
\  {{ r = SQRT ( 10 * cos ( 2 * t ) ) }} ;       \ (8)雙紐線圖
\  {{ r = 10 }} ;                                \ (9)正圓圈
\  {{ r = ABS ( sin ( t ) ) }} ;                 \ (10)上下雙圓圖
\  {{ r = 1 + cos ( t ) * sin ( t ) ^ 2 }} ;     \ (11)三凸輪圖
\  {{ r = 2 - sin ( 7 * t ) - ( cos ( 30 * t ) / 2 ) }} ; \ (12)苔蘚圖
\  {{ r = ABS ( sin ( t ) ) }} ;                 \ (13)up and down circles
\  {{ r = ABS ( 2 * ( 1 + sin ( t ) ) ) }} ;     \ (14)up cardioid
\  {{ r = ABS ( 3 * cos ( 3 * t ) ) }} ;         \ (15)6 leaved Ross
\  {{ r = ABS ( 2 + 3 * cos ( t ) ) }} ;         \ (16)limacon
\  {{ r = 3 * t }} ;                             \ (17)archimedian Spiral
\  {{ r = exp ( 3 * t ) }} ;                     \ (18)logarithmic spiral
\  {{ r = 2 / ( 1 - 0.8 * cos ( t ) ) }} ;       \ (19)橢圓,關鍵在0.8-->0.99
\  {{ r = cos ( 5 * t ) + ( 4.5 ) * cos ( t ) }} ; \ (20)heart to bell
\  {{ r = cos ( 7 * t / 2 ) }} ;

: rEvaluate BASIC
10 REM r evaluate
20 FOR I = 0 TO N
30 LET { degree = I>R ( I ) * 360 / I>R ( N ) }
40 LET { t = ( degree / 180 ) * FPI }
50 RUN r(t)
60 LET { RR ( I ) = r }
70 NEXT I
80 END ;

: RmaxFind BASIC
10 REM Rmax find out
20 LET { Rmax = RR ( 0 ) }
30 FOR I = 0 TO N
40 LET { Rmax = MAX ( Rmax RR ( I ) ) }
50 NEXT I
60 END ;

: PolarToCartesianConvert BASIC
10 REM polar to cartesian convert
20 FOR I = 0 TO N
30 LET { degree = I>R ( I ) * 360 / I>R ( N ) }
    :: { t = ( degree / 180 ) * FPI }
    :: { XX ( I ) = 250 + ( RR ( I ) * cos ( t ) * 200 / Rmax ) }
    :: { YY ( I ) = 250 - ( RR ( I ) * sin ( t ) * 200 / Rmax ) }
40 NEXT I
50 END ;

: DataPreparation ( -- )
  rEvaluate
  RmaxFind
  PolarToCartesianConvert ;

: PolarPlot
BASIC

100 REM circles plot
110 run 1 SetBkMode: demo-dc
120 run black SetTextColor: demo-dc
130 RUN LTgreen    LINECOLOR: demo-DC
140 RUN 250 250  50    CIRCLE: demo-DC
150 RUN 250 250 100    CIRCLE: demo-DC
160 RUN 250 250 150    CIRCLE: demo-DC
170 RUN 250 250 200    CIRCLE: demo-DC

200 REM radiation scale lines plot
210 FOR I = 0 TO 360 STEP 10
220 LET { degree = I>R ( I ) }
     :: { t = ( degree / 180 ) * FPI }
     :: { X = 250 + 200 * cos ( t ) }
     :: { Y = 250 - 200 * sin ( t ) }
230 LET XI = INT ( X ) :: YI = INT ( Y )
240 RUN  XI  YI MOVETO: demo-DC
250 RUN 250 250 LINETO: demo-DC
260 NEXT I

300 REM text print
310 run   4   4 S" Fig. Polar Plot" textout: demo-dc
320 RUN   4  21 S" r=sin(4*t)*cos(8*t)" TEXTOUT: demo-DC

330 RUN   4 460 S" R(max)    = " TEXTOUT: demo-DC
340 RUN   4 480 S" scale/div = " TEXTOUT: demo-DC

350 RUN 490 251 S" X" TEXTOUT: demo-DC
360 RUN 252   1 S" Y" TEXTOUT: demo-DC

400 REM rmax, scale/division floating point values print
410 RUN 98 460 Rmax (FG.) TEXTOUT: demo-DC
420 LET { r = Rmax / 4 }
430 RUN 98 480    r (FG.) TEXTOUT: demo-DC

500 REM x axis and y axis plot
510 RUN ltblue LINECOLOR: demo-DC
520 RUN 250   2  MOVETO: demo-DC
530 RUN 250 504  LINETO: demo-DC
540 RUN   2 250  MOVETO: demo-DC
550 RUN 498 250  LINETO: demo-DC

600 REM axis scale marks plot
610 FOR I = 50 TO 450 STEP 50
620 RUN 250  I MOVETO: demo-DC
630 RUN 260  I LINETO: demo-DC
640 RUN  I 250 MOVETO: demo-DC
650 RUN  I 240 LINETO: demo-DC
660 NEXT I

900 REM function curve plot
910 RUN LTRED LINECOLOR: demo-DC
920 LET XI = INT ( XX ( 0 ) ) :: YI = INT ( YY ( 0 ) )
930 RUN XI YI MOVETO: demo-DC
940 FOR I = 1 TO N
950 LET XI = INT ( XX ( I ) ) :: YI = INT ( YY ( I ) )
960 IF ( ( XI - 250 ) ^ 2 + ( YI - 250 ) ^ 2 ) > 40400 THEN 980
\ 970 RUN XI YI LINETO: demo-DC
\ 970 RUN XI YI BLACK SETPIXEL: demo-DC
970 RUN LTRED BRUSHCOLOR: demo-DC
972 RUN XI YI 2 FILLCIRCLE: demo-DC
980 NEXT I

990 run frame
1000 END
;
' PolarPlot is plot2

\ ---------------------------------------------------------------
\ Top Level program starts here
\ ---------------------------------------------------------------

: WINPLOT       ( -- )
                Start: DEMOW
                StartPos: DEMOW 50 + swap 50 + swap message-origin
                blue line-color
                RANDOM-INIT             \ initialize random number generator
                erase-demo  SetWhiteBG  \ 20140325 ***
                begin   Refresh: DEMOW
                        key             \ handle keyboard interpretation
                        case
                        'O' +k_control  of  open-demo-bitmap            endof
                        '1'             of   1 save-bitmap              endof
                        '2'             of   4 save-bitmap              endof
                        '3'             of   8 save-bitmap              endof
                        '4'             of  16 save-bitmap              endof
                        '5'             of  24 save-bitmap              endof
                        '6'             of  32 save-bitmap              endof
                        'S' +k_control  of  16 save-bitmap              endof
                        'V' +k_control  of  paste-demo-bitmap           endof
                        'P' +k_control  of  print-demo                  endof
                        'Q' +k_control  of  16 print-demo-bmp           endof
\ -----------------------------------------------------------------------------
                        k_F1            of  about-demo                  endof
\ -----------------------------------------------------------------------------
\ 增加可用功能鍵直接繪出圖形功能,讓各種圖形可以疊加存在。

                        K_F2            OF  PLOT2                       ENDOF
                        K_F3            OF  PLOT3                       ENDOF
                        K_F4            OF  PLOT4                       ENDOF
                        K_F5            OF  PLOT5                       ENDOF
                        K_F6            OF  PLOT6                       ENDOF
                        K_F7            OF  PLOT7                       ENDOF
                        K_F8            OF  PLOT8                       ENDOF
                        K_F9            OF  PLOT9                       ENDOF
\ -----------------------------------------------------------------------------
\ 停止但保存所繪之圖,可以回到系統操作畫面,並透過相同操作繼續繪製想疊加之圖。

                        K_F10           OF  EXIT                        ENDOF
\ -----------------------------------------------------------------------------
                        k_cr            of  run-demo                    endof
                        k_cr +k_control of  line-walk                   endof
                        k_esc           of  erase-demo  SetWhiteBG      endof          \ ***
                       k_esc +k_control of                              endof
                'P' +k_control +k_shift of  GetHandle: DEMOW
                                            Setup: ThePrinter           endof
                'C' +k_control          of  false copy-demo-bitmap      endof
                'C' +k_control +k_shift of  true  copy-demo-bitmap      endof
                'X' +k_control          of  false copy-demo-bitmap
                                            k_esc pushkey               endof
                        endcase
                again   ;


\ ---------------------------------------------------------------

: main
  DataPreparation
  winplot
;

page
cr cr
.( Usage: ) cr
.( main --> K_F2 )
main