まず 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
#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,
&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 バージョンのプログラム。
| ターミナルで入手&コンパイル&実行 |
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);
/* */
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;
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() が良く分からない。