September 18, 2011

繪製 Mandelbrot Set 的小程式

工作的空檔,偶然想起 fractals (碎形),為紀念去年因胰臟癌過世的 Benoît Mandelbrot 大師 (1924-2010),就嘗試撰寫繪製 Mandelbrot Set 的小程式,藉以體驗自我相似結構的美妙。這個程式採用最單純的圖像格式 [PPM],基本上把寬度與高度的資訊描述好,就是逐一填入像素資料。程式碼如下:(mandelbrot.c)
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
 
#define width_size      800
#define height_size     600
#define Maxval          255

static const float orig_x = width_size * 2/3;
static const float orig_y = height_size * 1/2;

typedef struct _pixel {
    unsigned char r;
    unsigned char g;
    unsigned char b;
} pixel;

static const pixel dim_gray = { 105, 105, 105 };

static unsigned char iteration(int x, int y)
{
    const int limit = Maxval + 1;
    int i;
    complex c = ((x - orig_x) / (width_size / 3)) +
                ((orig_y - y) / (height_size / 2)) * I;
    complex z = 0;

    for (i = 0; i < limit; i++) {
        /* basic formula */
        z = z * z + c;
        if (creal(z) > 2 || cimag(z) > 2)
            break;
    }
    return (unsigned char) (i == limit ? 0 : i);
}


int main()
{
    FILE *f = fopen("mandelbrot.ppm", "w+");

    /* PPM header */
    fprintf(f,
            "P6\n"      /* PPM magic number */
            "#Mandelbrot Set\n"
            "%d "       /* width, in ASCII decimal */
            "%d\n"      /* height, in ASCII decimal */
            "%d\n",     /* maximum color value, in ASCII decimal */
            width_size, height_size, Maxval);

    /* Write every pixel generated by Mandelbrot Set */
    for (int i = 0; i < height_size; i++) {
        for (int j = 0; j < width_size; j++) {
            unsigned char iter = iteration(j, i);
            if (iter) {
                pixel p = {
                    .r = iter,
                    .g = (float) abs(j - orig_x) / width_size * Maxval,
                    .b = (float) abs(i - orig_y) / height_size * Maxval };
                fwrite(&p, sizeof(pixel), 1, f);
            } else {
                fwrite(&dim_gray, sizeof(pixel), 1, f);
            }
        }
    }

    fclose(f);
    return 0;
}
程式利用 C99 提供的複數型態 (complex),很直覺地演繹 Mandelbrot set 的基本公式,相關的原理與繪製技巧可見 [How to Plot the Mandelbrot Set By Hand],編譯並執行本程式:
$ gcc -Wall -std=c99 mandelbrot.c -o mandelbrot && ./mandelbrot
當程式執行完畢,會輸出 "mandelbrot.ppm",可使用 GIMP 或桌面環境內建的瀏覽工具來觀賞,畫面如下:

程式以反覆代入方程式的方式,計算結果來得到上述圖形,並加以彩繪,基本上就是控制像素的 RGB 比例。關於背景知識,可參考非常詳盡的中文參考資料 [碎形 Fractal]。
由 jserv 發表於 11:53 PM | 迴響 (0)

September 14, 2011

演講:Android 圖形系統 -- 設計與實做分析

九月 24 日 (週六) 小弟將在高雄市作免費的技術分享,此次主題為「Android 圖形系統 -- 設計與實做分析」,以下摘錄 [Study-Area 活動訊息]:
  • 議題:Android 圖形系統:設計與實做分析
  • 議程簡介:同事在深度移植 Android 後,在 COSCUP 2011 分享經驗時,傳達了一個重要的概念:「欲征服 Android,必先征服GUI」,誠然,Android 的圖形系統不僅反映了應用程式開發的思維,也與硬體特性和演進息息相關,本議程嘗試分析現有 Android 系統架構,並由系統移植與開發的角度,探索跨程序資料交換、OpenGL|ES 引擎、2D 系統,以及 RenderScript 等相關設計。
  • 預定議題大綱:
    • 從 Android 內部資料交換開始
    • 圖形系統分析
    • 2D 與硬體加速
    • OpenGL|ES 工業標準與擴充
    • RenderScript
  • 活動時間:9 月 24 日13:30~17:00 (課後另有餐會交流)
  • 活動地點:高雄市苓雅區中正二路 30 號 8 F (樹德科技大學推廣教育中心 802 教室)
此議題預計延續去年在台中分享的「Android 系統元件探討」,更細緻地探討 Android 圖形系統背後的關鍵設計概念,希望對台灣許多對 Android 系統移植與產品化有興趣的朋友,能有些幫助,同時也總結從 2008 年底以來,移植 Android 以及自 2009 年開始在 [0xlab] 改良 Android 系統的經驗。歡迎各界朋友前來指教,當然,這一系列的演講都會是免費的,不久的未來,預期會涵蓋 Android 無線通訊與系統工具的設計議題。
由 jserv 發表於 2:29 PM | 迴響 (0)

September 2, 2011

致歉:網站資料佚失

應該半年前甚至更早就該發布此聲明,不過一直因為工作而耽擱,特別是曾有一度想把這個 blog 關閉。每個月都會接獲來信,告知網站連結失效、內容錯亂,甚至連在 blog 留言或搜尋都有問題,而坐視這些問題不顧,實在是本人的疏失,請多包涵。

首先,感謝這幾年來持續協助小弟處理網站資料的朋友,像是小州、Andrew、Rex,還有四元等 (應一併把台大計中、交大網路,甚至中研院的 admin 算入,但實在無法具體指出相關的人名)。最早在 info.sayya.org 零星放一些檔案作分享,也沒想到一放就歷經了十年,更沒想到 2004 年玩票性寫了 blog,竟然持續至今。雖然工作與興趣都是接觸最新的資訊技術,但在使用工具的方面,我個人卻很不習慣新的工具,blog.linux.org.tw 大概只剩下我這個唯一的使用者,而且幾乎沒有換過版型,後端的 MovableType 系統沿用至今 (有記憶以來,2003 年就長這樣),原本該被嫌棄過度老舊,沒想到竟然有網友說小弟的 blog 版面很清爽、看起來很專業,對此,還真不知道該怎麼回應。

儘管對於重要資料做了備份,但一直沒對網站資料作 1:1 的備份,於是,一旦硬碟出了狀況 (包含異地備份也出問題,可見小弟實在太久沒用心),從網站連結到若干網路服務,幾乎都處於失效的狀態,對此,真是非常抱歉,但目前還沒想出比較有效率的回復方式。我想,倘若您需要特定的連結所指向的檔案,煩請來函 <jserv.tw@gmail.com> 告知,小弟將嘗試參考檔名自備份區取出該資料,謝謝!另外,blog 的意見回應功能也是失效的狀態,煩請多利用 email。
由 jserv 發表於 2:15 AM | 迴響 (0)