Lab 9-2: CComplex 的應用與 Mandelbrot 圖形界面

 
實習目標 使用實習 3-1, 4-2 中的CComplex 類別
做一個 Mandelbrot 碎形動畫
練習與基本圖形界面的合作
練習視窗界面程式的 debug
 
步驟一 這個實習接續 9-1, 我們稍微修改一下 Mandelbrot 類別的界面, 讓它能夠支援一個 Mandelbrot 動畫的程式, 範例執行程式 Mandelbrot03a, 這個程式會慢慢畫出每計算一次 z = z * z + c 之後的圖形, 在狀態列會顯示目前已經作了多少次了, 以及每一次有多少個點發散掉了, 程式一直執行到 256 次為止

在任何時候, 你可以用滑鼠左鍵點兩下來暫停動畫, 也可以用選單上的暫停模擬來暫停動畫, 然後你可以用滑鼠左鍵在視窗中指定一個區域來放大顯示, 重新點兩下可以繼續執行, 另外使用右鍵點選可以更換一組顏色。

步驟二 請下載圖形界面程式碼 Mandelbrot03b.rar, 解壓縮出來, 請編譯並且執行, 你應該可以看到視窗中是全部空白的, 選單中有 檔案/暫停動畫 的選項, 如同上一個實習, 我們將在這個 project 中應用你先前寫的 CComplex 類別來撰寫程式
步驟三 首先在 ClassView 中你可以找到 Mandelbrot 類別, 打開這個類別你可以看到下列類別的定義以及空的成員函式:
    class Mandelbrot  
    {
    public:
    	int updateData(int **&data, int currentIteration);
    	void generateData(int **&data, int numIterations);
    	Mandelbrot(double centerX, double centerY, 
    	           double range, int windowSize);
    	virtual ~Mandelbrot();
    
    private:
    ...
    };
這個類別和前一個實習裡的 Mandelbrot 大同小異, 主要的界面修改
    int updateData(int **&data, int currentIteration);
是為了支援動畫的繪製, 為了繪製動畫, Mandelbrot 物件不能一次在 generateData() 函式內把整個圖形都計算完, 而必須要每次當 updateData() 被呼叫後, 在 updateData() 裡計算一個回合而已,

首先建構元函式會傳進來繪圖中心點的複數平面的座標, 例如 (-0.5, 0), 以及繪圖區域的寬與高 (目前所畫的是一個方形區域), 例如 2.3, 以及視窗顯示區域的點數, 例如 500, 請在 Mandelbrot 類別中設計常數 (const) 資料成員記錄下來, 例如:

    const double m_range;
    const double m_centerY;
    const double m_centerX;
    const int m_windowSize;
除此之外, 類別內也需要有一個 m_windowSize x m_windowSize 的二維複數陣列, 主要目的是記錄每一回合計算後 z 的數值, 這個陣列我們為了節省記憶體, 還是用下圖動態的方式來配置:
建構元中必須負責配置這個二維陣列, 解夠元中必須負責釋放這個二維陣列
步驟四 這個類別也需要用到複數的類別, 請由前一個實習中拷貝進來
步驟五
    void generateData(int **&data, int numIterations);
這個函式和前一個實習中實作的 generateData() 概念相同, 每次被呼叫到時, 代表繪圖界面程式需要知道在 numIterations 回合的限制下有多少點發散掉了; 但是這一次的 generateData() 負責的事情較少, 它不需要去配置記憶體並且修改 data 指標變數了, 它仍然需要計算 numIterations 個回合, 算出每一個點經過多少回合才會發散, 並且將結果記錄在 data 陣列中,

對於所有沒有發散的點, data[i][j] 都必須設定為 0

對於所有沒有發散的點, 目前所計算出來的 z 值必須記錄下來, 以便後續在 updateData() 函式中繼續計算 z = z * z + c

步驟六
    int updateData(int **&data, int currentIteration);
每次 updataData() 被呼叫到時代表界面程式需要下一個時間點的動畫資料, 請根據先前所記錄下來的 z 值, 繼續運用 z = z * z + c 計算下一個回合的 data[i][j] 數值, 基本上只需要對於 data[i][j] 為 0 的資料來計算就可以了, data[i][j] 不等於 0 的點事實上都已經發散了, 不需要在繼續算下去, 如果在計算的過程中發現某一個點發散掉了, 請將 data[i][j] 設為 currentIteration, 這個傳進來的 currentIteration 數值代表目前進行到第幾個回合了
步驟七 請將所完成的 project (去掉 debug/ 資料匣下的所有內容) 壓縮起來儲存在 cyber 上你的帳號內, 後面的實習課程可能需要使用這裡所完成的程式

C++ 物件導向程式設計課程 首頁

製作日期: 05/02/2004 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 電機資訊學院 資訊工程系 Lagoon