GLSC3D の勧め
桂田 祐史

2017 年 12 月 2 日, 2017 年 12 月 10 日, 2022 年 10 月 31 日

はじめに

1

GLSC3D1 は、北海道大学の秋山正和2 氏を中心とするチームによって開発・保守がされているグラフィックス・ライブラリィである。長い間、使われて来た GLSC (Graphic Library for
Scientiﬁc Computing) の後継というべきソフトウェアである。
マニュアル [1] は WWW 上に置かれている。
特徴を (独断で) 述べると• OpenGL 3.3+GLSL に基づく 3D 描画機能
• 最近の環境を基礎にした設計(GLSC は、X Window System を利用していて、オリジナルの龍谷大学版の最終更新日
時が 1995 年)• 動画の作成も快適に行える(GLSC のやや弱かった面が大幅に改善された)• GLSC と使い方が似ているので、GLSC に慣れている人にはとっつきやすい• GLSC と共存が可能(似ているが別物で、一つのシステムに両方インストールしても何ら問題がない)
コンピューター・システムの性能向上により、空間 3 次元のシミュレーションが比較的気軽に出来るようになってきている。その可視化の手段として GLSC3D は真っ先にあげられる選択肢になる。

2

Mac へのインストール

2.1

インストール手段の選択理由

GLSC3D では、Mac, Windows, Linux 環境がサポートされているが、Mac はメインの扱いのようで (？)、現象数理学科のメンバーとしてはとても心強い。
二つのインストール手段が提供されている。
1. 「最小限でインストール」
いわゆるバイナリー・インストールであるが、(良くあるように) OS のバージョンごとにバイナリーが用意されていないので、しばしば警告が出る。
1
2

http://www-mmc.es.hokudai.ac.jp/~masakazu/\#section14
http://www-mmc.es.hokudai.ac.jp/~masakazu/

1

2. 「フルインストール」
ソースプログラムからコンパイルしてライブラリィを生成する。Xcode と MacPorts を利用する。
ゼミの学生が持っている Mac (現象数理学科 Mac) の状況を考えると (Xcode と MacPorts
は入っている、結構古い macOS を使っている人がいる)、フルインストールが適当であると
考える。

2.2

準備

(1) (これはオプションで、やらなくても多分大丈夫) macOS のアップグレード — これは必要ではないけれど、前からアップグレードしようかどうか迷っていた人には、この機会にやってみることを勧める。アップグレード自身に長い時間がかかり、アップグレードすると Xcode, MacPorts の再インストールも必要になるので、かなりの時間がかかる。でも、どうせ (2) をするならば、この機会に macOS のアップグレードをするのはトータルでトクになるかもしれない。
(2) Xcode のアップデート• 最初に Xcode を起動できるかどうか確認すること。macOS をアップグレードした人の中には、Xcode がなくなっている人もいる。Xcode がなくなっている人は、App
Store でインストールすること。
• Xcode がある人の場合、左上の林檎マーク→「この Mac について」→ [ソフトウェ
ア・アップデート] で表示されるところに Xcode があれば、アップデートする。
• アップデートするときに、大量のファイルをダウンロードする必要があるので、この作業は、時間に余裕があるときに、高速なネット接続があるところで行うこと。大学でするのは (日曜日でもない限り) 勧められない。
(3) MacPorts のアップデート
ターミナルでsudo port selfupdate
sudo port upgrade outdated

を実行する。
(sudo を知らない人に: コマンドを管理者権限で実行するためのコマンドである。最初にsudo を用いるとき、その意味を理解しているかどうか警告される。パスワード入力を求められる。パスワードの後に enter(return) を入力する。パスワードを打っても (盗み見されないよう) 画面には表示されないことに注意する。)
もしかすると、最新の MacPorts をインストールするように促されるかもしれない (がんばって英語を読むこと)。その場合は https://www.macports.org/install.php から自分の macOS に適合するバージョンをダウンロードしてからインストール。
参考: https://trac.macports.org/wiki/Migration, http://nalab.mind.meiji.ac.
jp/~mk/knowhow-2017/node32.html(4) フルインストール用ファイル Script on mac.zip の入手
http://www3.u-toyama.ac.jp/akiyama/Software/Script_on_mac.zip を適当な場所 (ターミナルで作業しやすい場所) に保存する。
2ターミナルで入手curl -O http://www3.u-toyama.ac.jp/akiyama/Software/Script_on_mac.zip

本当は「現象数理学科 Mac の環境の更新マニュアル」みたいなのを作るべきかもしれない(素材は既にあちこちに書き散らしてある)。

2.3

フル・インストール手順

unzip Script_on_mac.zip
cd Script_on_mac./1_Install_macports_mac./2_Install_dependency_library_mac./3_Test_GLSC3D_on_mac
途中で “Do you want to run the Sample Program? (YES=1, NO=0)”, “Do you wantto run the Advanced Program? (YES=1, NO=0)” と尋ねられる。

./4_Install_GLSC3D_on_your_mac


コマンドの名前が長目であるが、全部タイプする必要はない。例えば 1 Install macports macを入力するためには、./1 をタイプした後に tab キーを押すと良い。
GLSC Working Directory というディレクトリィが残り、「消しても構わない」という意味のメッセージが出るが、サブディレクトリィ GLSC3D にソース・プログラム Hello GLSC3D.cが残っているので、残しておく方が良いかもしれない。
また、~/bin/ccg というスクリプトがインストールされるので、自分でコンパイル＆実行
するには例えば次のようにすれば良い。


cd ~/GLSC3D_Working_Directory
ccg Hello_GLSC3D.c./Hello_GLSC3D



2.4



「最小限」から「フル・インストール」への切り替え手順「最小限」でインストールしたが、「フル・インストール」に切り替えたい場合の手順を以下に述べる。
「最小限」のファイルのディレクトリィ3 に UninstallGLSC3D というスクリプトが残っている4 。これを実行してから、前項の手順を踏む、が大まかな内容であるが、途中で sudo port
install libpng が必要のようだ。

3

もう消してしまった人は、もう一度ファイルを入手すれば良い。
/usr/local/lib と /usr/local/include にインストールしたファイルと /usr/local/bin/ccg を削除する、という内容。
4

3





cd GLSC3D_mac_minimum/./UninstallGLSC3D
unzip Script_on_mac.zip
cd ../Script_on_mac./1_Install_macports_mac./2_Install_dependency_library_mac
sudo port install libpng./3_Test_GLSC3D_on_mac./4_Install_GLSC3D_on_your_mac


無事インストール出来たかどうか確認するには、例えば



cd ~/GLSC3D_Working_Directoryls
ccg Hello_GLSC3D.c./Hello_GLSC3D.c(HEllo GLSC3D プログラムを、インストールした ccg でコンパイルして実行できるかど
うか)




~/GLSC3D Working Directory/ の下に GLSC3D というディレクトリィがあり、そこに C プ
ログラムがある (例えばサンプル・プログラムのソースプログラムは Src の下にある。)。


cd GLSC3D/Samplesls
ccg Sample_g_pyramid.c./Sample_g_pyramid


2.5



ドキュメントマニュアル [1] の PDF ファイルが用意されている。
「GLSC3D (Ver. 3.0.1) Manual 構想・制作・監督：秋山 正和」5
この手のものは、ソースプログラムもドキュメントの一部かもしれない (読んで勉強になるから)。フルインストール後には、ホームディレクトリィの下に GLSC3D Working Directory/GLSC3Dというディレクトリィが残り、その下の Src にソース・プログラムが置かれている。

C, C++プログラムのコンパイル3

大抵の場合、スクリプト ccg を使う、で OK.



ccg なんとか.c




あるいは
5

http://www3.u-toyama.ac.jp/akiyama/Software/Manual/GLSC3DManual/GLSC3D_Manual.pdf

4





ccg なんとか.cpp


GLSC3D で提供される ccg には二種類ある。
1. 「フルインストール」でインストールされるもの
普通、~/bin にコピーされる。インクルードファイル (glsc3d 3.h, glsc3d 3 math.h)は ~/include に、ライブラリィ・ファイル (GLSC3D の libglsc3d.a) は、~/lib に置いてあると想定してある。


ccg



if [ ${1##*.} = cpp ]thenc++ ${1} -W -Wall -O2 -I ~/include -L ~/lib -lglsc3d_3 -framework OpenGL -L/opt/local/lib -lsdl
else
cc ${1} -W -Wall -O2 -I ~/include -L ~/lib -lglsc3d_3 -framework OpenGL -L/opt/local/lib -lsdl2fi

2. 「最小限」でインストールされるもの
普通、/usr/local/bin にコピーされる。インクルードファイルは /usr/local/includeに、ライブラリィ・ファイル (GLSC3D の libglsc3d.a 以外に、libpng, libfreetype など) は、/usr/local/lib に置いてあると想定してある。
自分がどちらを実行しているか知りたいときはwhich ccg
とすると良い (/usr/local/bin/ccg ならば、おそらくは「最小限」の方)。
Mac の場合は、インクルード・ファイル、ライブラリィ・ファイルを移動しても問題がない。その場合、スクリプト・ファイルを適当に書き換えれば良い。

4

GLSC ユーザーのための情報

4.1

公式ドキュメントから引用

0. #include <glsc.h> を #include <glsc3d 3.h> に変更。
1. g init の ウィンドウサイズ指定は int でピクセル単位にする。
2. g device, g term は消す。
3. g def scale は g def scale 2D に変更。std 座標はピクセル単位になっているので変更(3 倍ぐらい?) する必要あり。
4. 描画終わりに g finish を挿入。
5. 全ての色指定は (r, g, b, a) に変更。
6. g move, g plot, g box, g circle の後ろに 2D をつける。
7. g polyline, g polygon, g data plot, g contln の後ろに 2D をつける。
8. g text は g text standard に変更。std 座標の変更。
5

9. g bird view, g hidden は g bird view 3D に変更。引数も変更。
10. g sleep(G STOP); の G STOP マクロはないので、-1 などとおく。
11. g def scale で座標を決めるのに使った長方形の枠を描くときは、従来は g box で描いていたが、glsc 3d では g box 2d ではなく g boundary を使う。
12. g sel scale が呼ばれた時点では g clipping(0) になっているので、g boundary で描
かれる枠の外にも絵を描きたいときは、g sel scale を 呼んだ直後に g clipping(1)としておく。
13. アニメを作るとき、動くオブジェクトを部分的に塗りつぶして、再描画するという方法を取っていた場合、うまくいかなくなっている。g cls でクリアして、全体を再描画するように変更する。
文責: 小林亮(桂田注) 一番大事なのは g finish() を挿入することかも。他はコンパイラーがこんな関数知らないとか、引数がおかしいとか教えてくれるけれど、g finish() については指摘してくれないから。

4.2

プログラム例 1: 1 変数関数のグラフ

これは以前書いた「GLSC の紹介」4 節6 のプログラムを書き直したもの。
ターミナルで入手&コンパイル&実行curl -O https://m-katsurada.sakura.ne.jp/misc/20171202/draw-graph-GLSC3D.c
ccg draw-graph-GLSC3D.c./draw-graph-GLSC3D/** draw-graph-GLSC3D.c -- 1 変数関数のグラフを描く*
コンパイル: ccg draw-grap-GLSC3D.c*/#include <stdio.h>#include <math.h>#ifdef OLD#define G_DOUBLE#include <glsc.h>#else#include <glsc3d_3.h>#endifdouble pi;
int main(){
int i, n;double a, b, c, d;double h, x;6

http://nalab.mind.meiji.ac.jp/~mk/labo/howto/intro-glsc/node6.html

6

double f(double);#ifdef OLD
char title[100];#endifdouble win_width, win_height, w_margin, h_margin;
pi = 4 * atan(1.0);/* 表示する範囲 [a,b] × [c,d] を決定 */a = - 10 * pi; b = 10 * pi; c = - 2.0; d = 2.0;/* 区間の分割数 n */n = 200;/* GLSC の開始
メタファイル名、ウィンドウ・サイズの決定 */#ifdef OLD
win_width = 200.0; win_height = 200.0; w_margin = 10.0; h_margin = 10.0;#else
win_width = 600.0; win_height = 600.0; w_margin = 30.0; h_margin = 30.0;#endifg_init("GRAPH", win_width + 2 * w_margin, win_height + 2 * h_margin);#ifdef OLD/* 出力デバイスの決定 */g_device(G_BOTH);#endif/* 座標系の定義: [a,b] × [c,d] という閉領域を表示する */#ifdef OLD
g_def_scale(0,a, b, c, d,
w_margin, h_margin, win_width, win_height);#else
g_def_scale_2D(0,a, b, c, d,
w_margin, h_margin, win_width, win_height);
g_cls(); // ないとマズイ？
#endif/* 線を二種類用意する */#ifdef OLD
g_def_line(0, G_BLACK, 2, G_LINE_SOLID);
g_def_line(1, G_RED,
0, G_LINE_SOLID);#else// 線の type は用意されていない#define G_LINE_SOLID (0)g_def_line(0, 0, 0, 0, 1, 2, G_LINE_SOLID);
g_def_line(1, 1, 0, 0, 1, 2, G_LINE_SOLID);// 太くしないと点線のように見える#endif/* 表示するための文字列の属性を定義する */#ifdef OLD
g_def_text(0, G_BLACK, 3);#else
g_def_text(0, 0, 0, 0, 1, 24); // 文字のサイズの単位が全然違う#endif/* 定義したものを選択する */g_sel_scale(0); g_sel_line(0); g_sel_text(0);/* 座標軸を描く */#ifdef OLD
g_move(a, 0.0); g_plot(b, 0.0);
g_move(0.0, c); g_plot(0.0, d);7

#elseg_move_2D(a, 0.0); g_plot_2D(b, 0.0);
g_move_2D(0.0, c); g_plot_2D(0.0, d);#endif/* タイトルを表示する */#ifdef OLD
sprintf(title, "Bessel function J0(x) (%g<=x<=%g)", a, b);g_text(20.0, 10.0, title);#else
g_text_standard(60.0, 30.0, "Bessel function J0(x) (%f<=x<=%f)", a, b);#endif/* 刻み幅 */h = (b - a) / n;/* グラフを描くための線種の選択 */g_sel_line(1);/* 折れ線でグラフを描く */#ifdef OLD
g_move(a, f(a));#elseg_move_2D(a, f(a));#endiffor (i = 1; i <= n; i++) {x = a + i * h;#ifdef OLD
g_plot(x, f(x));#else
g_plot_2D(x, f(x));#endif}#ifndef OLD
g_finish();#endif/* ユーザーのマウス入力を待つ */printf("終りました。X の場合はウィンドウをクリックして下さい。\n");g_sleep(-1.0);/* ウィンドウを閉じる */#ifdef OLD
g_term();#endifreturn 0;}
double f(double x){/* 0 次 Bessel 関数 */return j0(x);}• (前項の繰り返し) g finish() は忘れないように。
• glsc.h のかわりに glsc3d 3.h をインクルードする。以前のように G REAL はなくなったので、G DOUBLE を定義したりする必要はない。
• g text() で printf() のような書式が使えるようになったので、char 型の配列を準備して、sprintf() を呼び出す必要はなくなった。
• g init() でウィンドウ・サイズを指定するとき、以前はプリントしたときの長さ (mm)が単位だったのを、ドット数 (ピクセル数, ただし float 型) が単位に変更された。こういう名前が同じで仕様が異なる関数が導入されるのは困ったことだが、まあ受け入れ可8能なレベルである。3 倍程度にするというのには同意 (例えば 200 mm = 20 cm を 600
ピクセルにする)。

• g {def,sel} scale() でも単位が長さ (mm) からドット数に変更されたので、g init()
での変更に応じて、数値を大きくする必要がある。
• g device() は不要であると。確かにファイル出力のしかけが変わったからな。
• 以前は最初に黒板を消す必要、もとい g cls() を実行する必要はなかったが、それが必須になった？ゴミが表示される (勘違いでなければ)。
• 線のタイプを名前では指定できないようになった。これは少しまずいんじゃないかな。
マジック・ナンバーの埋め込みには反対。
• 実線を指定したつもりで、線の太さが小さいと、点線のように見えることがある。バグ？
• 線の色を名前でなく、R, G, B で指定するようになった。同じ名前の関数の仕様を変えてしまうのは、率直に言って賛成できない変更。関数の名前を変える方が良かった (C++ではないので、多重定義というわけにはいかないのか)。
• g def text() で文字のサイズを指定する方法も変わったけれど、この辺はオリジナルでは単位もあやふやだったので仕方がないと考える。…昔は文字を描くのは大変で、色々なことが思い出されるけれど、今は freetype もあるし、スマートに解決できた、と言っていいのかも。ぱちぱちぱち。

4.3

プログラム例 2: 2 変数関数のグラフの等高線＆鳥瞰図

まず GLSC バージョンのプログラムを掲げる。


ターミナルで入手&コンパイル&実行

curl -O https://m-katsurada.sakura.ne.jp/misc/20171202/test-contln.c
cglsc test-contln.c./test-contln

/** test-contln.c --- 左側に等高線、右側にグラフの bird view を描く*
cglsc test-contln.c*/#include <stdio.h>/* 動的に確保できる行列 matrix */#include <stdlib.h>
typedef double **matrix;
matrix new_matrix(int, int);
void delete_matrix(matrix);#include <math.h>#ifndef G_DOUBLE#define G_DOUBLE#endif#include "glsc.h"#define W0 80.0
#define H0 80.0

9





#define W1 80.0
#define H1 80.0
#define W_MARGIN 10.0
#define H_MARGIN 10.0
double pi;
void compute(double (*)(double, double), matrix,
double, double, double, double,
int, int);
double f(double, double);double max(double x, double y) { return (x > y) ? x : y; }int main(){
int m, n, k;
double xmin, xmax, ymin, ymax;
matrix u;
pi = 4 * atan(1.0);/* 分割数 */m = 100; n = 100;/* 定義域は [-π, π] × [-π, π] */xmin = - pi; xmax = pi; ymin = - pi; ymax = pi;/* 格子点における数値を納める変数 */if ((u = new_matrix(m+1,n+1)) == NULL) {fprintf(stderr, " 行列のためのメモリーが確保できませんでした。\n");return 1;}/* GLSC */g_init("Meta", W0 + W1 + 3 * W_MARGIN, max(H0, H1) + 2 * H_MARGIN);
g_device(G_BOTH);/* ウィンドウ 0 */g_def_scale(0,xmin, xmax, ymin, ymax,
W_MARGIN, H_MARGIN, W0, H0);
g_def_scale(1,xmin, xmax, ymin, ymax,
W_MARGIN + W0 + W_MARGIN, H_MARGIN, W1, H1);/* */g_def_line(0, G_BLACK, 0, G_LINE_SOLID);
g_def_text(0, G_BLACK, 2);/* 定義したものを呼び出す */g_sel_scale(0);g_sel_line(0);g_sel_text(0);/* title */g_text(W_MARGIN + W0 * 0.6, H_MARGIN / 2, "contour and bird view");/* 格子点上での関数値を計算する */compute(f, u, xmin, xmax, ymin, ymax, m, n);/* 等高線 */for (k = -10; k <= 10; k++)g_contln(xmin, xmax, ymin, ymax, &u[0][0], m+1, n+1, 0.1 * k);/* 鳥瞰図 */g_hidden(1.0, 1.0, 0.4,
-1.0, 1.0,/* 視点 (距離, 方角を表わす (θ, φ) ) */5.0, 30.0, 30.0,
W_MARGIN + W0 + W_MARGIN, H_MARGIN,
W1, H1,10

&u[0][0], m + 1, n + 1, 1,
G_SIDE_NONE, 2, 1);
printf("終了したらウィンドウをクリックして終了してください。\n");g_sleep(-1.0);
g_term();return 0;}/** [xmin,xmax] × [ymin,ymax] を x 軸方向に m 等分、y 軸方向に n 等分して* 各格子点上の f の値を u に格納する。
*/
void compute(double (*f)(), matrix u,
double xmin, double xmax, double ymin, double ymax,
int m, int n){
int i, j;double dx, dy, x, y;
dx = (xmax - xmin) / m;dy = (ymax - ymin) / n;for (i = 0; i <= m; i++) {x = xmin + i * dx;for (j = 0; j <= n; j++) {y = ymin + j * dy;u[i][j] = f(x, y);}}}double f(double x, double y){return sin(3 * x) * sin(y);}matrix new_matrix(int m, int n){
int i;
double *dp;
matrix p;
if ((p = malloc(sizeof(double *) * m)) == NULL) {fprintf(stderr, "new_matrix(): cannot allocate memory\n");return NULL;}
if ((dp = malloc(sizeof(double *) * m * n)) == NULL) {fprintf(stderr, "new_matrix(): cannot allocate memory\n");free(p);return NULL;}
for (i = 0; i < m; i++)p[i] = dp + i * n;return p;}
void delete_matrix(matrix a){free(a[0]);free(a);}次に GLSC3D バージョンのプログラム。

11

ターミナルで入手＆コンパイル&実行

curl -O https://m-katsurada.sakura.ne.jp/misc/20171202/test-contln-GLSC3D.c
ccg test-contln-GLSC3D.c./test-contln-GLSC3D

/** test-contln-GLSC3D.c --- 左側に等高線、右側にグラフの bird view を描く*
ccg test-contln-GLSC3D.c*/#include <stdio.h>/* 動的に確保できる行列 matrix */#include <stdlib.h>
typedef double **matrix;
matrix new_matrix(int, int);
void delete_matrix(matrix);#include <math.h>#include "glsc3d_3.h"
double pi;
void compute(double (*)(double, double), matrix,
double, double, double, double,
int, int);
double f(double, double);double max(double x, double y) { return (x > y) ? x : y; }#define W0 480.0#define H0 480.0#define W1 480.0#define H1 480.0#define W_MARGIN 50.0
#define H_MARGIN 50.0
int main(){
int m, n, k;
double xmin, xmax, ymin, ymax;
matrix u;
pi = 4 * atan(1.0);/* 分割数 */m = 100; n = 100;/* 定義域は [-π, π] × [-π, π] */xmin = - pi; xmax = pi; ymin = - pi; ymax = pi;/* 格子点における数値を納める変数 */if ((u = new_matrix(m+1,n+1)) == NULL) {fprintf(stderr, " 行列のためのメモリーが確保できませんでした。\n");return 1;}
g_init("Meta", W0 + W1 + 3 * W_MARGIN, max(H0, H1) + 2 * H_MARGIN);
g_def_scale_2D(0,xmin - 0.1, xmax + 0.1, ymin - 0.1, ymax + 0.1,
W_MARGIN, H_MARGIN, W0, H0);
g_def_scale_3D(1,xmin, xmax, ymin, ymax, -1.2, 1.2,
xmin, xmax, ymin, ymax, -1.2, 1.2,
W_MARGIN + W0 + W_MARGIN, H_MARGIN, W1, H1);
/* */

12





g_def_line(0, 0, 0, 0, 1, 1, 0);
g_def_text(0, 0, 0, 0, 1, 24);g_sel_line(0);g_sel_text(0);/* 定義したものを呼び出す */g_sel_scale(0);g_move_2D(xmin, ymin); g_plot_2D(xmax, ymin); g_plot_2D(xmax, ymax);
g_plot_2D(xmin, ymax); g_plot_2D(xmin, ymin);/* */g_cls();/* title */g_text_standard(W_MARGIN + W0 * 0.8, H_MARGIN / 2, "contour and bird view");/* 格子点上での関数値を計算する */compute(f, u, xmin, xmax, ymin, ymax, m, n);/* 等高線 */for (k = -10; k <= 10; k++) {g_contln_f_2D(xmin, xmax, ymin, ymax, m+1, n+1, &u[0][0], 0.1 * k);//g_finish(); // 毎回呼ぶとおかしくなる。
}//g_finish(); // ここで呼ぶと、次の鳥瞰図を描いた後消えてしまう/* 鳥瞰図 */g_sel_scale(1);g_bird_view_f_3D(xmin, xmax, ymin, ymax,
m + 1, n + 1,
&u[0][0],0, 1);
g_finish();printf("終了したらウィンドウをクリックして終了してください。\n");g_sleep(-1.0);
return 0;}/** [xmin,xmax] × [ymin,ymax] を x 軸方向に m 等分、y 軸方向に n 等分して* 各格子点上の f の値を u に格納する。
*/
void compute(double (*f)(), matrix u,
double xmin, double xmax, double ymin, double ymax,
int m, int n){
int i, j;double dx, dy, x, y;
dx = (xmax - xmin) / m;dy = (ymax - ymin) / n;for (i = 0; i <= m; i++) {x = xmin + i * dx;for (j = 0; j <= n; j++) {y = ymin + j * dy;u[i][j] = f(x, y);}}}double f(double x, double y){return sin(3 * x) * sin(y);}matrix new_matrix(int m, int n){
int i;

13

double *dp;
matrix p;
if ((p = malloc(sizeof(double *) * m)) == NULL) {fprintf(stderr, "new_matrix(): cannot allocate memory\n");return NULL;}
if ((dp = malloc(sizeof(double *) * m * n)) == NULL) {fprintf(stderr, "new_matrix(): cannot allocate memory\n");free(p);return NULL;}
for (i = 0; i < m; i++)p[i] = dp + i * n;return p;}
void delete_matrix(matrix a){free(a[0]);free(a);}g finish() が良く分からない。

4.4

自分用のメモGLSC3D では、線の色を RGB で指定することになっている。まあ、何となく分かるけれど、
従来の仕方を残して欲しかった (人間に覚えさせるのは反対。上山パッチみたいに rgb color()というのを別に作れば良かったにと思う。)。
1. 黒 0,0,0
2. 赤 1,0,0
3. 緑 0,1,0
4. 青 0,0,1
5. マゼンタ 1,0,1
6. 黄色 1,1,0
7. シアン 0,1,1
8. 白 1,1,1線の不透明度 a は、0 ≤ a ≤ 1 の範囲であるが、a = 1 だと従来と同じ (と思っていいのかな？)。
線の太さは、0 から 8 までの整数で、大きいほど太い。基準が良く分からない (というのは
GLSC と同じか)。
線の種類は、0 から 8 までの整数で指定できるが、説明はない。GLSC を真似ているのかな？ (少なくとも 0 は実線で、1 は点線である。) Cf. GLSC の glsc.h には、次のように定義されている (今度 GLSC と GLSC3D で比較してみよう)。

14





#define G_LINE_SOLID#define G_LINE_DOTS#define G_LINE_DASHED#define G_LINE_LONG_DASHED#define G_LINE_THIN_DOTS#define G_LINE_DOT_DASHED#define G_LINE_D_DOT_DASHED#define G_LINE_RESERVED



(0)
(1)
(2)
(3)
(4)
(5)
(6)
(7)



画像の保存のために、g capture set(char *dirname) と g capture(void) という関数が用意されている。前者で画像を保存するディレクトリィを指定して、後者で画像の PNG ファ
イルを (連番ファイル名で) 出力する。動画作成を念頭においた仕様なのだろう。(もちろん、そういうのがあっても良いけれど、単純にファイルのパス名を指定して保存する関数を用意してもらいたかった。)

A

講習会のサンプル・プログラムを読む

A.1

はじめに

以下のプログラムは 2017/11/？ の講習会で解説されたものである。
例えば 1 CreateWindows.c をコンパイル・実行するには

ccg 1_CreateWindow.c./1_CreateWindow







とすれば良い。
GLSC のグラフィックスのウィンドウで esc を入力するとウィンドウが閉じられる。

A.2

1 CreateWindow.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


1 CreateWindow.c#include<stdio.h>#include<glsc3d_3.h>
int main(){g_init("Window", 600, 600); //Pixel Sizeg_def_scale_2D(0,//ID-1, 1,//xmin,xmax-1, 1,//ymin,ymax
20.0, 20.0, //Window (Left, Top) Position
560, 560);//Window Size (x,y)
g_cls();//Clear windowg_sel_scale(0);//Select Virtual scale
g_boundary();//Draw Boundaryg_finish();//flush Draw buffer
g_sleep(10.0);//Sleep 10 sec
return 0;}• 2 行目 glsc.h でなく glsc 3d.h をインクルード。
15

• 6 行目 ウィンドウのサイズの単位はピクセルであることに注意。
• 7 行目 g def scale() でなくて g def scale 2D() という名前であるが、引数の意味は
g def scale() と同様。
• 14 行目• 15 行目 g finish() これを適当なタイミングで実行するのが、GLSC とは違うところ。

A.3

2 VectorField.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


VectorField.c#include<stdio.h>#include<glsc3d_3.h>
int main(){g_init("Window", 600, 600); //Pixel Sizeg_def_scale_2D(0,//ID-1, 1,//xmin,xmax-1, 1,//ymin,ymax
20.0, 20.0, //Window (Left, Top) Position
560, 560);//Window Size (x,y)
g_cls();//Clear windowg_sel_scale(0);//Select Virtual scale
g_boundary();//Draw Boundary
int Imax = 10;
int Jmax = 10;
double VecX; double VecY;
for(int i = 1; i < Imax; i ++){for(int j = 1; j < Jmax; j ++){double x = i*0.2 - 1.0, y = j*0.2 - 1.0;
VecX = x; VecY = y;// Divergence//VecX = -y; VecY = x; // Rotation
g_arrow_2D(x, y,
VecX, VecY,
0.1,
0.05,
2);
}
}
g_finish();g_sleep(10.0);
return 0;// Base Point// Direction// Size of Arrow Length// Size of Arrow Head// Arrow kinds//flush Draw buffer//Sleep 10 sec}

• 26 行目 g arrow() というのは、オリジナルの GLSC にはなく、後から導入されたコマ
ンドで、g arrow 2D() は GLSC3D における 2 次元バージョン。注釈のおかげで意味はほぼ分かる。最後の引数は Arrow kinds だそうだけど、マジック・ナンバーなのはちょっ
と嫌。

16

A.4

3 Animation.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33




Animation.c#include<stdio.h>#include<glsc3d_3.h>
int main(){int INTV = 100;g_init("Window", 600, 600);
g_def_scale_2D(0,-1, 1,-1, 1,
20.0, 20.0,
560, 560);//Pixel Size//ID//xmin,xmax//ymin,ymax//Window (Left, Top) Position//Window Size (x,y)//////////// Start time loop ////////////for (int i_time = 0; ; i_time++) {double dt = 0.0001;//Time Discritization
double t = i_time * dt;//Time//////////// Calculation Part ////////////
double x = 0.5 * cos(2.0*M_PI * t);//X Coordinate
double y = 0.5 * sin(2.0*M_PI * t);//Y Coordinate//////////// Draw Part ////////////
if (i_time%INTV == 0) {g_cls();//Clear windowg_sel_scale(0);//Select Virtual scale
g_boundary();//Draw Boundary
g_area_color(1,0,0,1);//Area Colorg_circle_2D(x, y, 0.1, G_NO, G_YES);//g_circle_2D
g_finish();//flush Draw buffer
g_sleep(0.01);//Sleep 0.01 sec}}
return 0;}• 19 行目円周率を意味する M PI は、C 言語の規格には入っていないけれど (だから GCC,LLVM にはあるけれど、Visual Studio の C コンパイラーでは定義されていない？)、定義されていないときは GLSC3D で定義するのだそうです。
• 26 行目 g area color() という名前の関数は、GLSC にもあるけれど、引数が変わっている。R, G, B, と不透明度を並べるのだとか。
• 27 行目 g circle() ...g circle 2D()

17

18

A.5

4 Wave 2D Contln.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64



Wave 2D Contln.c/******************************************************************************************
This program solves a wave equation using the explicit method.
A wave equation is utt = c * c * uxx.
The function f is the initial shape of wave.
Time loop in this program consists of"Calculation part" and "Draw Part".
Calculation part is controlled by the interval parameter INTV.
This numerical result is visualized by using "g_contln_2D" of GLSC3D.
*******************************************************************************************/#include<stdio.h>#include<glsc3d_3.h>#define N (100)#define M (100)double f(double x,double y){return 3 * exp(-((x - M_PI / 2)*(x - M_PI / 2) + (y}int main(){double- 3 * M_PI / 2)*(yx, y;doubledoubledoubledoubledoubledoubleLx = 8 * M_PI;
Ly = 8 * M_PI;
dx = Lx / N;
dy = Ly / M;
dt = 0.002;
c = 1.0;

doubledoubledoubleu0[N + 2][M + 2];
u1[N + 2][M + 2];
u2[N + 2][M + 2];

doubledoublelambda_x = c * dt / dx;
lambda_y = c * dt / dy;

int

INTV = 100;g_init("Window", 600, 600); //Pixel Sizeg_def_scale_2D(0,-Lx*0.5, Lx*0.5,-Ly*0.5, Ly*0.5,
20.0, 20.0,
560, 560);//ID//xmin,xmax//ymin,ymax//Window (Left, Top) Position//Window Size (x,y)//Set initial calculation{//Step1for(int j = 1;j < M + 1; j ++){y = (j - 0.5) * dy;for(int i = 1;i < N + 1; i ++){19
x = (i - 0.5) * dx;
u0[i][j] = f(x,y);- 3 * M_PI / 2))/ 0.

1
utt = uxx + uyy (境界条件は同次 Neumann なのか
c2な) を差分法で解いた解を可視化する (等高線を描く) プログラム。

• 長方形領域上の 2 次元波動方程式• g line color() も g area color() とおなじく、R, G, B, 不透明度を引数に取る。
• 長方形 [xmin , xmax ] × [ymin , ymax ] で定義された関数 u があるとき、定義域を x 軸方向に Nx 等分, y 軸方向に Ny 等分して格子を作り、格子点での値 u(xi , yj ) (0 ≤ i ≤ Nx ,0 ≤ j ≤ Ny ) を 2 次元配列 u[nx+1,ny+1] に記録してあるとする。このとき関数値がlevel である等高線を描くには、
g contln 2D(xmin, xmax, ymin, ymax, nx+1, ny+1, u, level);とすれば良い。

20

21

A.6

5 Turing 2D Contln.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

5 Turing 2D Contln.c/******************************************************************************************
This program solves reacrtion-diffusion equations using the explicit method.
Reacrtion-diffusion equations are ut = du uxx + f(u,v) and vt = dv vxx + g(u,v).
Time loop in this program consists of"Calculation part" and "Draw Part".
Calculation part is controlled by the interval parameter INTV.
This numerical result is visualized by using "g_contln_2D" of GLSC3D.
*******************************************************************************************/#include<stdio.h>#include<stdlib.h>#include<glsc3d_3.h>#define N (100)#define M (100)double f(double u, double v){
return u * (1 - u * u) - v;}
double g(double u, double v){
return 3.0 * u - 2.0 * v;//
return 3.0 * (u + 0.05) - 2.0 * v;//
return 3.0 * (u - 0.05) - 2.0 * v;}
int main(){doubledoubledoubledoubledoubledoubledoubleLx = 100.0;
Ly = 100.0;
dx = Lx / N;
dy = Ly / M;
dt = 0.001;
du = 1.0;
dv = 10.0;

doubledoublelambda_u = du * dt / (dx * dx);
lambda_v = dv * dt / (dy * dy);

doubledoubledoubledoubleu0[N + 2][M + 2];
u1[N + 2][M + 2];
v0[N + 2][M + 2];
v1[N + 2][M + 2];

int INTV = 200;g_init("Window", 600, 600); //Pixel Sizeg_def_scale_2D(0,//ID-Lx*0.5, Lx*0.5,//xmin,xmax-Ly*0.5, Ly*0.5,//ymin,ymax
20.0, 20.0,//Window (Left, Top) Position
560, 560);//Window Size (x,y)//Set initial calculation{//Step1
22
double u_Init_Sum = 0.0;
double v_Init_Sum = 0.0;• 反応拡散方程式 (reaction diﬀusion equations) を差分法で解いて、等高線を描くプログ
ラム。

23

24

A.7

6 Turing 2D ColorMap.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

6 Turing 2D ColorMap.c/******************************************************************************************
This program solves reacrtion-diffusion equations using the explicit method.
Reacrtion-diffusion equations are ut = du uxx + f(u,v) and vt = dv vxx + g(u,v).
Time loop in this program consists of"Calculation part" and "Draw Part".
Calculation part is controlled by the interval parameter INTV.
This numerical result is visualized by using "g_color_map" made in thie program.
*******************************************************************************************/#include<stdio.h>#include<stdlib.h>#include<glsc3d_3.h>#define N (100)#define M (100)//////////// Color map: g_color_map ////////////
void g_color_map(double Array[][M+2],
double dx_width, double dy_width,
double L_bottom_x, double L_bottom_y,
double max, double min){
int Fine_Grid = 1;
for (int j=0; j < M+2; j++) {for (int i=0; i < N+2; i++) {if (Fine_Grid == 0) {g_area_color((Array[i][j]-min)/(max-min), 0, 1.0-(Array[i][j]-min)/(max-min), 0.5
g_box_center_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y, dx_widt}

if (Fine_Grid == 1) {double tmpColor;
if (j-1<0) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i][j-1]*0.5;
g_area_color((tmpColor-min)/(max-min), 0, 1.0-(tmpColor-min)/(max-min), 1);g_triangle_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y,
dx_width * (i) + L_bottom_x - dx_width*0.5, dy_width * (j) + L_bott
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bott
G_NO, G_YES);

if (i+1>=N+2) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i+1][j]*0.5;
g_area_color((tmpColor-min)/(max-min), 0, 1.0-(tmpColor-min)/(max-min), 1);g_triangle_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y,
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bott
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bott
G_NO, G_YES);

if (j+1>=M+2) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i][j+1]*0.5;
g_area_color((tmpColor-min)/(max-min), 0, 1.0-(tmpColor-min)/(max-min), 1);g_triangle_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y,
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bott
dx_width * (i) + L_bottom_x - dx_width*0.5, dy_width * (j) + L_bott
G_NO, G_YES);

25
if (i-1<0) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i-1][j]*0.5;• 反応拡散方程式 (reaction diﬀusion equations) を差分法で解いて、レベルを色で表したプログラム。

26

27

A.8

7 Wave 2D ColorMap.c

7 Wave 2D ColorMap.c/******************************************************************************************
This program solves a wave equation using the explicit method.
A wave equation is utt = c * c * uxx.
The function f is the initial shape of wave.
Time loop in this program consists of"Calculation part" and "Draw Part".
Calculation part is controlled by the interval parameter INTV.
This numerical result is visualized by using "g_color_map".
*******************************************************************************************/#include<stdio.h>#include<glsc3d_3.h>#define N (100)#define M (100)//////////// Color map: g_color_map ////////////
void g_color_map(double Array[][M+2],
double dx_width, double dy_width,
double L_bottom_x, double L_bottom_y,
double max, double min){
int Fine_Grid = 1;
for (int j=0; j < M+2; j++) {for (int i=0; i < N+2; i++) {if (Fine_Grid == 0) {g_area_color((Array[i][j]-min)/(max-min), 0, 1.0-(Array[i][j]-min)/(max-min), 0.5);
g_box_center_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y, dx_width, d}if (Fine_Grid == 1) {double tmpColor;
if (j-1<0) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i][j-1]*0.5;
g_area_color((tmpColor-min)/(max-min), 0, 1.0-(tmpColor-min)/(max-min), 1);g_triangle_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y,
dx_width * (i) + L_bottom_x - dx_width*0.5, dy_width * (j) + L_bottom_y
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bottom_y
G_NO, G_YES);

if (i+1>=N+2) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i+1][j]*0.5;
g_area_color((tmpColor-min)/(max-min), 0, 1.0-(tmpColor-min)/(max-min), 1);g_triangle_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y,
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bottom_y
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bottom_y
G_NO, G_YES);

if (j+1>=M+2) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i][j+1]*0.5;
g_area_color((tmpColor-min)/(max-min), 0, 1.0-(tmpColor-min)/(max-min), 1);g_triangle_2D(dx_width * (i) + L_bottom_x, dy_width * (j) + L_bottom_y,
dx_width * (i) + L_bottom_x + dx_width*0.5, dy_width * (j) + L_bottom_y
dx_width * (i) + L_bottom_x - dx_width*0.5, dy_width * (j) + L_bottom_y
G_NO, G_YES);

28
if (i-1<0) tmpColor = Array[i][j];else tmpColor = Array[i][j]*0.5 + Array[i-1][j]*0.5;

• 2 次元波動方程式
ログラム。

1
utt = uxx + uyy を差分法で解いた解を値を色で表して可視化するプ
c2

29

30

A.9

8 Wave 2D BirdView.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64



8 Wave 2D BirdView.c/******************************************************************************************
This program solves a wave equation using the explicit method.
A wave equation is utt = c * c * uxx.
The function f is the initial shape of wave.
Time loop in this program consists of"Calculation part" and "Draw Part".
Calculation part is controlled by the interval parameter INTV.
This numerical result is visualized by using "g_bird_view_3D" of GLSC3D.
Please note that this program set "g_def_scale_3D".
*******************************************************************************************/#include<stdio.h>#include<glsc3d_3.h>#define N (100)#define M (100)double f(double x,double y){return 3 * exp(-((x - M_PI / 2)*(x - M_PI / 2) + (y}int main(){double- 3 * M_PI / 2)*(yx, y;doubledoubledoubledoubledoubledoubledoubleLx = 8 * M_PI;
Ly = 8 * M_PI;
Lz = 8 * M_PI;
dx = Lx / N;
dy = Ly / M;
dt = 0.002;
c = 1.0;

doubledoubledoubleu0[N + 2][M + 2];
u1[N + 2][M + 2];
u2[N + 2][M + 2];

doubledoublelambda_x = c * dt / dx;
lambda_y = c * dt / dy;

int

INTV = 100;g_init("Window", 600, 600); //Pixel Sizeg_def_scale_3D_fix(0,//ID-Lx*0.5, Lx*0.5,//xmin,xmax-Ly*0.5, Ly*0.5,//ymin,ymax-Lz*0.5, Lz*0.5,//zmin,zmax
20.0, 20.0,//Window (Left, Top) Position
560, 560);//Window Size (x,y)
//
//
//
//
//

g_vision(0,0.0, -Ly, Lz,
0.0, 0.0, 1.0,
1.25);//Set initial calculation
{

//ID
//eye
//up
//zoom31- 3 * M_PI / 2))/ 0.

1
utt = uxx + uyy を差分法で解いた解をのグラフの鳥瞰図 (bird view)c2
を描くプログラム。

• 2 次元波動方程式

32

33

A.10

9 Diffusion 1D.c

9 Diffusion 1D.c#include<stdio.h>#include<glsc3d_3.h>#define N (200)
int main(){double x;
double L = 5;
double dx = L / N;double t = 0.0;
double dt = 0.0001;
double u[N + 2];
double tmpu[N + 2];
double D = 1.0;
int
INTV = 100;g_init("Window", 600, 320); //Pixel Sizeg_def_scale_2D(0,//ID-L*0.5, L*0.5,//xmin,xmax-0.2, 1.2,//ymin,ymax
20.0, 20.0,//Window (Left, Top) Position
560, 280);//Window Size (x,y)//Set initial calculation{//Step1for(int i = 1;i < N + 1; i ++){x = i*dx - L*0.5;
u[i] = exp(-(x*x));}//Step2
u[0] = u[1];u[N + 1] = u[N];}//////////// Start time loop ////////////for (int i_time = 0;t < 10 ; i_time++) {t = i_time * dt;//////////// Draw Part ////////////
if (i_time%INTV == 0) {g_cls();//Clear windowg_sel_scale(0);//Select Virtual scale
g_line_color(0.0, 0.0, 0.0, 1.0);
g_boundary();//Draw Boundaryg_line_width(1.0);
g_line_color(0.0, 0.0, 0.0, 0.5);
g_move_2D(-L*0.5, 0.0); g_plot_2D(L*0.5, 0.0); //X Axis
g_move_2D(0.0, -1.2); g_plot_2D(0.0, 1.2);//Y Axis//Profile of u
g_line_width(2.0);
g_line_color(1.0, 0.0, 0.0, 1.0);
for (int i=0; i<N-1; i++) {g_move_2D(i*dx-L*0.5, u[i]);g_plot_2D((i+1)*dx-L*0.5, u[i+1]);}
g_text_size(18);g_text_color(1.0, 0.0, 0.0, 1.0);
g_text_2D_virtual(L*0.5 - 0.4, 1.0, "u: -");
g_finish();g_sleep(0.0);}//flush Draw buffer
34 0.0 sec//Sleep• 空間 1 次元の拡散方程式のグラフを描くプログラム。

35

36

A.11

10 Diffusion 1D Text.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64



10 Diffusion 1D Text.c#include<stdio.h>#include<glsc3d_3.h>#define N (200)
int main(){double x;
double L = 5;
double dx = L / N;double t = 0.0;
double dt = 0.0001;
double u[N + 2];
double tmpu[N + 2];
double D = 1.0;
int
INTV = 100;g_init("Window", 900, 320); //Pixel Sizeg_def_scale_2D(0,//ID-L*0.5, L*0.5,//xmin,xmax-0.2, 1.2,//ymin,ymax
20.0, 20.0,//Window (Left, Top) Position
560, 280);//Window Size (x,y)
g_def_scale_2D(1,//ID-L*0.5, L*0.5,//xmin,xmax-0.2, 1.2,//ymin,ymax
620.0, 20.0,//Window (Left, Top) Position
260, 280);//Window Size (x,y)//Set initial calculation{//Step1for(int i = 1;i < N + 1; i ++){x = i*dx - L*0.5;
u[i] = exp(-(x*x));}//Step2
u[0] = u[1];u[N + 1] = u[N];}//////////// Start time loop ////////////for (int i_time = 0; t < 10; i_time++) {t = i_time * dt;//////////// Draw Part ////////////
if (i_time%INTV == 0) {g_cls();//Clear window//////////// Graph Part ////////////{
g_sel_scale(0);//Select Virtual scale
g_line_color(0.0, 0.0, 0.0, 1.0);
g_boundary();//Draw Boundaryg_line_width(1.0);
g_line_color(0.0, 0.0, 0.0, 0.5);
g_move_2D(-L*0.5, 0.0); g_plot_2D(L*0.5, 0.0);
g_move_2D(0.0, -1.2); g_plot_2D(0.0, 1.2);//Profile of u
g_line_width(2.0);
g_line_color(1.0, 0.0, 0.0, 1.0);
for (int i=0; i<N-1; i++) {37 u[i]);g_move_2D(i*dx-L*0.5,
g_plot_2D((i+1)*dx-L*0.5, u[i+1]);//X Axis//Y Axis• 空間 1 次元の拡散方程式のグラフを描くプログラムという点では、9 Diffusion 1D.c と同じ。凡例というのか、パラメーターや現在時刻を表示する。そのために、二つの scaleを定義している。

A.12

11 g def scale 2D.c



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29



11 g def scale 2D.c#include<stdio.h>#include<glsc3d_3.h>#define WINDOW_SIZE_X(600)#define WINDOW_SIZE_Y(300)
int main(){g_init("Window", WINDOW_SIZE_X, WINDOW_SIZE_Y);
g_def_scale_2D(0, -1, 1, -1, 1,
20.0, 20.0,
260.0, 260.0);
g_def_scale_2D(1, -1, 1, -1, 1,//
g_def_scale_2D(1, -2, 2, -2, 2,
320.0, 20.0,
260.0, 260.0);
for (int i_time = 0;; i_time++){g_cls();
g_sel_scale(0);g_boundary();g_circle_2D(0.0, 0.0, 1.0, 1, 1);
g_sel_scale(1);g_boundary();//g_area_color(0, 1, 0, 1);//
g_circle_2D(0.0, 0.0, 1.0, 1, 1);g_finish();}return 0;
}



•

38

A.13

12 g def scale 3D fix.c

12 g def scale 3D fix.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#include<stdio.h>#include<glsc3d_3.h>#define WX(600)#define WY(600)
int main(){g_init("Window", WX, WY);g_def_scale_3D_fix(0,-1, 1,-1, 1,-1, 1,
20.0, 20.0,
WX - 40.0, WY - 40.0);for (int i_time = 0;; i_time++){g_cls();
g_sel_scale(0);g_boundary();g_sphere_3D(0.0, 0.0, 0.0,
1.0, 0, 1);g_box_3D(-1, 1, -1, 1, -1, 1, 1, 0);g_finish();}return 0;
}



•

39

40

A.14


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

13 g vision.c
13 g vision.c#include<stdio.h>#include<glsc3d_3.h>#define WX(600)#define WY(600)
int main(){g_init("Window", WX, WY);g_def_scale_3D_fix(0,-1, 1,-1, 1,-1, 1,
20.0, 20.0,
WX - 40.0, WY - 40.0);
for (int i_time = 0;; i_time++){double a = -1;
g_vision(0,0, a, 4,0, 0, 1,
1.0);
g_cls();
g_sel_scale(0);g_boundary();g_box_3D(-1, 1, -1, 1, -1, 1, 1, 0);//X-Axes
g_area_color(1, 0, 0, 1);
g_arrow_3D(-1, -1, -1,
1.0, 0.0, 0.0,
2.0, 0.25,
0, 1);//Y-Axes
g_area_color(0, 1, 0, 1);
g_arrow_3D(-1, -1, -1,
0.0, 1.0, 0.0,
2.0, 0.25,
0, 1);//Z-Axes
g_area_color(0, 0, 1, 1);
g_arrow_3D(-1, -1, -1,
0.0, 0.0, 1.0,
2.0, 0.25,
0, 1);
g_area_color(1, 1, 0, 1);41g_cone_3D(0, 0, -1,



•

42

43

A.15

14 g def scale 3D 1.c



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46



14 g def scale 3D 1.c#include<stdio.h>#include<glsc3d_3.h>#define WX(600)#define WY(600)#define XLEN
#define YLEN
#define ZLEN
#define Imax
#define Jmax

(2.0 * M_PI)(2.0 * M_PI)(2.0 * M_PI)
(100)
(100)

int main(){g_init("Window", WX, WY);g_def_scale_3D_fix(0,-XLEN / 2, XLEN / 2,
-YLEN / 2, YLEN / 2,
-ZLEN / 2, ZLEN / 2,
20.0, 20.0,
WX - 40.0, WY - 40.0);
double u[Imax][Jmax];
double dx = XLEN / Imax, dy = YLEN / Jmax,rx,ry;}for(int i = 0;i < Imax;i ++){rx = (i + 0.5) * dx - XLEN / 2;
for(int j = 0;j < Jmax;j ++){ry = (j + 0.5) * dy - YLEN / 2;
u[i][j] = sin(rx * ry) * 0.5;}}
for (int i_time = 0;; i_time++){g_cls();
g_sel_scale(0);g_boundary();g_box_center_3D_core(0, 0, 0, XLEN, YLEN, ZLEN*0.5, 0, 1, 0);g_bird_view_3D(-XLEN / 2, XLEN / 2,
-YLEN / 2, YLEN / 2,
Imax, Jmax,u, 0, 1);g_finish();}return 0;
44


•

45

46

A.16

15 g def scale 3D 2.c



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

15 g def scale 3D 2.c#include<stdio.h>#include<glsc3d_3.h>#define WX(600)#define WY(600)#define XLEN
#define YLEN
#define ZLEN
#define Imax
#define Jmax

(2.0 * M_PI)(2.0 * M_PI)(2.0 * M_PI)
(100)
(100)

int main(){g_init("Window", WX, WY);// g_def_scale_3D_fix(0,//-XLEN / 2, XLEN / 2,//
-YLEN / 2, YLEN / 2,//
-ZLEN / 2, ZLEN / 2,//
20.0, 20.0,//
WX - 40.0, WY - 40.0);
g_def_scale_3D(0,-XLEN / 2, XLEN / 2,
-YLEN / 2, YLEN / 2,
-ZLEN / 4, ZLEN / 4,
-XLEN / 2, XLEN / 2,
-YLEN / 2, YLEN / 2,
-ZLEN / 2, ZLEN / 2,
20.0, 20.0,
WX - 40.0, WY - 40.0);
double u[Imax][Jmax];
double dx = XLEN / Imax, dy = YLEN / Jmax,rx,ry;for(int i = 0;i < Imax;i ++){rx = (i + 0.5) * dx - XLEN / 2;
for(int j = 0;j < Jmax;j ++){ry = (j + 0.5) * dy - YLEN / 2;
u[i][j] = sin(rx * ry) * 0.5;}}
for (int i_time = 0;; i_time++){g_cls();
47
g_sel_scale(0);



•

48

49

A.17


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

16 NewFunction1.c
16 NewFunction1.c#include<stdio.h>#include<glsc3d_3.h>#define WX(600)#define WY(600)
int main(){g_init("Window", WX, WY);g_def_scale_3D_fix(0,-1, 1,-1, 1,-1, 1,
20.0, 20.0,
WX - 40.0, WY - 40.0);
for (int i_time = 0;; i_time++){double dt = 0.01;
double t = i_time * dt;
g_vision(0,3 * cos(t), 3 * sin(t), 3,0, 0, 1,
1.0);
g_cls();
g_sel_scale(0);g_boundary();g_box_3D(-1, 1, -1, 1, -1, 1, 1, 0);//X-Axes
g_area_color(1, 0, 0, 1);
g_arrow_3D(-1, -1, -1,
1.0, 0.0, 0.0,
2.0, 0.25,
0, 1);//Y-Axes
g_area_color(0, 1, 0, 1);
g_arrow_3D(-1, -1, -1,
0.0, 1.0, 0.0,
2.0, 0.25,
0, 1);//Z-Axes
g_area_color(0, 0, 1, 1);
g_arrow_3D(-1, -1, -1,
0.0, 0.0, 1.0,
2.0, 0.25,
0, 1);
g_area_color(1, 1, 0, 1);50g_cone_3D(0, 0, -1,
0, 0, 1,



•

51

52

A.18

17 NewFunction2.c



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

17 NewFunction2.c#include<stdio.h>#include<glsc3d_3.h>#define WX(600)#define WY(600)
int main(){g_enable_highdpi();g_set_antialiasing(4);g_init("Window", WX, WY);g_def_scale_3D_fix(0,-1, 1,-1, 1,-1, 1,
20.0, 20.0,
WX - 40.0, WY - 40.0);

for (int i_time = 0;; i_time++){double dt = 0.01;
double t = i_time * dt;
g_vision(0,3 * cos(t), 3 * sin(t), 3,0, 0, 1,
1.0);
g_cls();
g_sel_scale(0);g_boundary();g_box_3D(-1, 1, -1, 1, -1, 1, 1, 0);//X-Axes
g_area_color(1, 0, 0, 1);
g_arrow_3D(-1, -1, -1,
1.0, 0.0, 0.0,
2.0, 0.25,
0, 1);//Y-Axes
g_area_color(0, 1, 0, 1);
g_arrow_3D(-1, -1, -1,
0.0, 1.0, 0.0,
2.0, 0.25,
0, 1);//Z-Axes
g_area_color(0, 0, 1, 1);
g_arrow_3D(-1, -1, -1,
0.0, 0.0, 1.0,
53
2.0, 0.25,
0, 1);



•

A.19


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20



18 Hinode Tuki 1.c
18 Hinode Tuki 1.c#include<stdio.h>#include<glsc3d_3.h>#define WINDOW_SIZE_X(800)#define WINDOW_SIZE_Y(400)
int main(){g_init("Hinode_Tuki", WINDOW_SIZE_X, WINDOW_SIZE_Y);
g_def_scale_2D(0, -4, 4, -2, 2,
0.0, 0.0,
WINDOW_SIZE_X, WINDOW_SIZE_Y);
for (int i_time = 0;; i_time++){g_cls();
g_sel_scale(0);g_boundary();g_finish();}return 0;
}



•

54

55

A.20

19 Hinode Tuki 2.c



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

19 Hinode Tuki 2.c#include<stdio.h>#include<glsc3d_3.h>#define WINDOW_SIZE_X(800)#define WINDOW_SIZE_Y(400)
int main(){g_init("Hinode_Tuki", WINDOW_SIZE_X, WINDOW_SIZE_Y);
g_def_scale_2D(0, -4, 4, -2, 2,
0.0, 0.0,
WINDOW_SIZE_X, WINDOW_SIZE_Y);
g_capture_set("");
double dt = 0.005, t,tmax = 5;
for (int i_time = 0;; i_time++){t = i_time * dt;
g_cls();
g_sel_scale(0);g_boundary();//Sorag_area_color(0.6, 0.6, 0.6, 1);g_box_2D(-4,4,-0.5,2,G_NO,G_YES);//Tukig_area_color(1, 1, 0, 1);
g_circle_2D(2.0, 1.0, 0.2, G_NO, G_YES);
g_area_color(0.6, 0.6, 0.6, 1);
g_circle_2D(1.8, 1.0, 0.2, G_NO, G_YES);//Taiyog_area_color(1, 0, 0, 1);
g_circle_2D(0.0, tanh(t) - 1, 0.5, G_NO, G_YES);//Umi
g_area_color(0.2, 0.6, 1, 1);g_box_2D(-4,4,-2,-0.5,G_NO,G_YES);//Mojiif(t > tmax){
g_text_standard(350, 100, "日本一!!");}
g_finish();g_capture();56• Frames.2017. 月. 日. 時. 分. 秒/ というディレクトリィを作り、000000.png, 000001.png,· · · という 6 桁の数 + .png という名前で画像ファイルを出力する。


ffmpeg -i Frames.2017. 月. 日. 時. 分. 秒/%06d.png なんとか.mpgとすると (%06d というのは printf() で用いる書式の流用である)、それら PNG ファイ
ルから なんとか.mpg という名前の動画ファイルを作る。

Bなぞ• g cls() を実行しないとゴミが表示される？
• g finish() を連続して実行するとおかしい。バッファーが空のときの動作が変、ということらしい。
• g contln f 2D() の動作が不安定。一度描いた等高線が消されてしまう？なぜ？
• マニュアルの関数の説明で引数の意味が書いていないことが多い。実験精神を発露させるか、ソースを読むか。

参考文献[1] 秋 山 正 和, 舘 入 数 磨, 舘 入 数 磨, 小 林 亮：GLSC3D (Ver. 3.0.0) Manual, http://www-mmc.es.hokudai.ac.jp/~masakazu/Software/Manual/GLSC3D_Ver3.0.
0Manual/GLSC3D_Manual.pdf (2017/11/22).

57