シダ(C、OpenGL、glut)

 

Windows、C、OpenGL、glutで

シダを描画しました

BASICでは描画過程を見ることが

出来ましたが

Cでは一瞬で描画されるので

リアルタイムで動かすことが

出来ます

 

'\','/'キーで前進後退

カーソルキーで方向転換

'p'で四角の表示非表示切り替え

'r'で逆回転

enterキー視点のリセット

です

 

leaf.cをコンパイルには

glut.h, glut32.lib, glut32.dll

が必要です

(昔ダウンロードしたので現在のリンクは

不明です

freeGlutなどが代わりにあるそうです)

glutはv-syncがオンにならなかったので

Sleepを入れてあります

(コメントを外すと時間待ちします)

 

Win32アプリでコンパイルすると

consoleウインドウは開きません

のでprintfは使えませんが

ウインドウが1個なので

見やすくなります

 

Consoleアプリでコンパイルすると

consoleウインドウが開きますので

printfが使えますがウインドウが

2個になり見た目が悪くなります

 

glutを使わずに作ったバージョンの

leaf.exeも同包しました

(こちらはv-sync同期です

また、glut32.dllは必要ありません)

 

etc21213.zip(leaf.c, leaf.exe)は

以下のリンクからダウンロードできます

VL-BASIC(N88-BASIC互換?)ホームページ

Readme.txtを読んで遊んで下さい

 

 

 

leaf.c

~.cはコメント以外のプログラムコードは自由に参考にして
使用して下さい
コメントを使用するときはULprojectの名を入れて下さい
 

/*                                                               leaf.c
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
シダ

Copyright(C) 2019-2020 ULpriject
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
INCLUDE FILE(s)
───────────────────────────────────*/
#ifdef WIN32
#include <windows.h>
#endif
#include "glut.h"
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MACRO(s)
───────────────────────────────────*/
#ifdef WIN32
#define state(key)    (GetAsyncKeyState(key) < 0)    /* 現在(& 0x8000) */
#define sleep(ms)    Sleep(ms)    
#else
#define state(key)    0
#define sleep(ms)    
#endif
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CONSTANT(s)
───────────────────────────────────*/
#ifdef WIN32
#define KEY_U    VK_UP
#define KEY_D    VK_DOWN
#define KEY_L    VK_LEFT
#define KEY_R    VK_RIGHT
#define KEY_B    VK_OEM_2        /* /? */
#define KEY_F    VK_OEM_102        /* \_ */
#else
#define KEY_U    0
#define KEY_D    0
#define KEY_L    0
#define KEY_R    0
#define KEY_B    0        /* /? */
#define KEY_F    0        /* \_ */
#endif
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
WINDOWS FUNCTION(s)
───────────────────────────────────*/
#ifdef _WINDOWS    /* #ifndef _CONSOLE */
void main(int argc, char** argv);
int WINAPI WinMain(HINSTANCE inst, HINSTANCE n, LPSTR arg, int show)
{
    int    argc = 1;
    char** argv = &arg;

    main(argc, argv);
    return 0;
}
#endif
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRIVATE VARIABLE(s)
───────────────────────────────────*/
static double leaf_d =  0.0;
static double leaf_s = -1.0;
static int    leaf_p =  1;
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRIVATE FUNCTION(s)
───────────────────────────────────*/
static
void display(void)
{
    glutSwapBuffers();
}
                                                                      /*
───────────────────────────────────*/
static
void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
}
                                                                      /*
───────────────────────────────────*/
static
void leaf(double size, int times)
{
    double x, y, r;
    int    i;

    x = y = 0.0;
    for (i = 0; i < times; i++)
    {
        glVertex2d(x * size, y * size);    /* 点 */
        r = ((double)rand()) / (1.0 + (double)RAND_MAX);
        if      (r < 0.01)
        {
            r = 0;
            y = y * 0.16;
        }
        else if (r < 0.01 + 0.07)
        {
            r = x * 0.20 - y * 0.26;
            y = x * 0.23 + y * 0.22 + 1.60;
        }
        else if (r < 0.01 + 0.07 + 0.07)
        {
            r = y * 0.28 - x * 0.15;
            y = x * 0.26 + y * 0.24 + 0.44;
        }
        else
        {
            r = x * 0.85 + y * 0.04;
            y = y * 0.85 - x * 0.04 + 1.60;
        }
        x = r;
    }
}
                                                                      /*
───────────────────────────────────*/
static
void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'p': leaf_p = !leaf_p; break;
    case 'r': leaf_s = -leaf_s; break;
    case ' ': glRotated(180, 0.0, 1.0, 0.0); break;
    case 13 : glLoadIdentity(); break;
    }
}
                                                                      /*
───────────────────────────────────*/
static
void move(void)
{
    double d = 0.5;
    double z = 5.0;

    if (state(KEY_U)) glRotated( d, 1.0, 0.0, 0.0);
    if (state(KEY_D)) glRotated(-d, 1.0, 0.0, 0.0);
    if (state(KEY_L)) glRotated(-d, 0.0, 1.0, 0.0);
    if (state(KEY_R)) glRotated( d, 0.0, 1.0, 0.0);
    if (state(KEY_B)) glTranslated(0.0, 0.0, -z  );
    if (state(KEY_F)) glTranslated(0.0, 0.0,  z  );
}
                                                                      /*
───────────────────────────────────*/
static
void idle(void)
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    /* r,g,b,a */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    move();

    /* 四角形 */
    if (leaf_p)
    {
        glPushMatrix();
        glTranslated(0.0, 0.0, -1080);
        glColor3d(0.8, 0.5, 0.0);
        glBegin(GL_QUADS);
            glColor3d(0.8, 0.5, 0.0);
            glVertex3d(-320, -180,   0);
            glVertex3d(-320,  180, -64);
            glVertex3d(   0,  180, -64);
            glVertex3d(   0, -180,   0);
        glEnd();
        glPopMatrix();
    }

    /* シダ */
    glPushMatrix();
    glTranslated(0.0, -180, -1080);
    glRotated(leaf_d, 0.0, 1.0, 0.0);
    leaf_d += leaf_s;
    glBegin(GL_POINTS);                /* 点 */
        glColor3d(0.0, 1.0, 0.0);
        leaf(40, 10000);
    glEnd();
    glPopMatrix();

    glFlush();            /* 上記glコマンドをすへて実行 */
    glutSwapBuffers();    /* Duble buffer(表示面と描画面)の切替 */
//    sleep(15);            /* 時間待ち(1000/60=16.6...ms */
}
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FUNCTION(s)
───────────────────────────────────*/
void main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitWindowSize(704, 396);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Leaf (ULproject)");

    glEnable(GL_DEPTH_TEST);        /* Depth buffer on */
    glMatrixMode(GL_PROJECTION);    /* 行列モード変更  */
    glLoadIdentity();                /* 単位行列        */
    /*          X0   X1    Y0   Y1    Z      Far */
    glFrustum(-320, 320, -180, 180, 720, 1000000);
    glMatrixMode(GL_MODELVIEW);        /* 行列モード変更  */
    glLoadIdentity();                /* 単位行列        */

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutIdleFunc(idle);                /* ここに処理を書く */

    glutMainLoop();                    /* 帰ってこない     */
}
 

午後(PM)12時は昼間か深夜か(2)

 

前回の結論は簡素か煩雑かでしたが

 

Wikipediaなどによりますと

昼の12時は

12:00:00 pm(p.m.)であり午前12:00:00

だそうです

 

24時間表記の時刻をT

12時間表記の時刻をtとすると

 0≦T<12は0(12)≦t<12 am

12≦T<24は0(12)≦t<12 pm

で、昼間の12時は12:00:00 pm

ですが、

 0<T≦12  は午前0<t≦12

12<T≦24(0)は午後0<t≦12

で、昼間の12時は午前12時

となると明治につくられた法令で

決められているそうです

(本当か?)

 

それによると

昼の1(13時)になる前までが午前で

1時(13時)から午後となるそうです

正午(昼の12時)より前と後で

分ける分け方と異なります

 

また、昼間の12時ちょうどまでが

午前でちょっとすぎれば午後である

という記述もあります

 

つまり、午前と午後の

時間帯の定義が複数あり

曖昧だと分かりました

 

この定義でいくと日付の変更は

0時は次の日ではなく前日で

0時をちょっとすぎれば日付が

変わるまたは、1時で変わる

という法律が日本には

まだあったりするのでしょうか

 

さらに、

午後12時=午前0時という記述も

みられ、同じ時刻に午前と午後が

混在しているのみならず、日付や

午前午後の切り替わるタイミングも

複数のルールが混在する事が

分かりました

 

am,pmの様に0時ちょうどで日付が

変わり、そのタイミングでpmからam

に変わり、昼の12時ちょうどでpm

に変わるとした方が、1つのルールに

なり簡素で分かりやすいと思います

 

このままだと

上司「今日の午前中までに仕上げろと言った

   はずだ、今何時だと思っている」

部下「昼の12時50分ですが、1時になるまで

   は午前中ですよね、だって日本の法律

   では昼の12時は午前12時ですよ」

上司「正午(昼の12時)からは午後なんじゃ

   ないのか?

   こんなややこしい法律変えてしまえ!」

 

という事が起こるかもしれません

 

結論

昼の12時は

am,pmだと

12:00:00 pm (昼の12時より前がam)

12:50:01 pm (0:50:01 pm)

 1:00:00 pm

となるが

午前,午後だと

午前12:00:00 (昼の12時までが午前?)

午前12:50:01又は(午後0:50:01)

午後 1:00:00 (昼の1時より前が午前?)

となり

昼の12時~1時付近の時間帯は

午前または午後がはっきりしない

という事が分かりました

昼の1時からは午後で間違い

なさそうです

 

感想

am,pmは簡素で分かりやすい

午前,午後は煩雑で分かりにくい

日本の法律を変えてam,pmと

同じにするべきだと思います

 

このブログの

N88-BASICで時計

午後(PM)12時は昼間か深夜か

アナログ時計(デジタルは24時間表示)と

24から12時間表記(AM,PM)に変換する

プログラムを公開しています

 

(VL-BASIC,NL-BASICのTIME$,DATE$

を書き換えてもシステム時刻は変更

されないので安心して変更して下さい

RUNやCLEARなどでシステム時刻に

戻ります)

 

NL-BASICとnl21209.zip(clock1n.bas, ampm001.bas)は

以下のリンクからダウンロードできます

NL-BASIC(N88-BASIC互換?)ホームページ

Readme.txtを読んで遊んで下さい

 

N88-BASICでケプラーの法則(2回目)~(5回目)

 

Keplerの第1~3法則などを導いていきます

 

この記事はリニューアルしました

https://ulprojectmail.blogspot.com/2021/10/kepler-1.html

天体の軌道(Kepler) (1回目)

https://ulprojectmail.blogspot.com/2021/10/kepler-2.html

天体の軌道(Kepler) (2回目)

 

https://ulprojectmail.blogspot.com/2021/10/kepler-3.html

天体の軌道(Kepler) (3回目)

https://ulprojectmail.blogspot.com/2021/10/kepler-4.html

天体の軌道(Kepler) (4回目)

 

N88-BASICでケプラーの法則(6回目)

 

前回、求めた、平均運動nを

使って軌道を描画します

 

重力定数μ=GM

s = (d/dt)S (Sの上付きドット)

と置く事にする

面積速度s = √(μℓ)/2 = const.

万有引力定数G,焦点質量M(太陽等)

 

P2/a3 = π2ℓ/s2 = const.

半直弦ℓ = a(1-e2) = q(1+e)

 

n = √(μ/a3)   (if e < 1)(楕)円

n = √(μ)      (if e = 1)放物線

n = √(μ/|a|3) (if e > 1)双曲線

n = 2π/P

 

a(AU), P(年), M=太陽を使うと

地球は、a = 1, P = 1なので

n = 2π/1 = √(μ/a3) = √μ

√μ = 2π

 

まとめ

n = 2πa3/2   (if e < 1)(楕)円

n = 2π      (if e = 1)放物線

n = 2π|a|3/2 (if e > 1)双曲線

経過時間t(年)

平均近点角M(rad)

M = nt

 

ケプラー方程式(楕円,放物線,双曲線)

M = u - esinu

M = u3/6 + qu

M = esinh(u) - u

 

離心近点角u, 真近点角f

u,fの変換式(楕円,放物線,双曲線)

tan(f/2) = √{(1+e)/(1-e)}tan(u/2)

tan(f/2) = u/√(2q)

tan(f/2) = √{(e+1)/(e-1)}tanh(u/2)

 

t=-0.5~0.5(-半年~半年)までの軌道を

(楕円),紫(放物線),水色(双曲線)で

描画しました。

 

NL-BASICとnl~.zip(kepl006.bas)は

以下のリンクからダウンロードできます

NL-BASIC(N88-BASIC互換?)ホームページ

Readme.txtを読んで遊んで下さい