調和近似
振動と波の授業で使う教科書スゲー丁寧!わかりやすい!先生の話聞く必要ない!
ばねのような単振動の運動方程式は

で表されます(kは色々変わります)
この形に持っていくことができれば、単振動(調和振動)です
高校物理ではおなじみの振り子ですが、運動方程式を立てると
 
 
(x:静止状態からの孤の長さ  l:半径)
のようになって、微妙に単振動にならないようです。今日知りました、ごめんなさい。単振動のようなうんどうをすると思ってたんですが、ちょこっと違うようです。
|x| << l という条件下のうちでは、テイラー展開の何乗かまでの項を使えばsinの部分がx/lになるので、晴れて単振動と同じ形になるようです。
これをいろいろ発展させていくと
ポテンシャルの極小点で起こる粒子の微小振動は、その点でポテンシャルの2階微分が0である場合を除いて、いつも近似的に単振動とみなしうることができることを示すことができるようです。
つまり、単振動ってのは特別な運動ではなく、一般のポテンシャル中で起きる普遍的なものであることがわかるんですよねぇ~
すごい!単振動すごい!見直した!
運動方程式やポテンシャルを単振動(調和振動)に近似するのを調和近似というみたいです
やっぱり物理は楽しいね
追記:dijkstra
ご指摘があったんですが、58行目の
min_dist[k] = min(min_dist[k], min_dist[min_idx]+dmat[min_idx][k]);
で関数でないものが呼び出されるというものなんですが、正直僕もなんでこんな風に書いたのかがわかりません(コラ)
ダイクストラ法で最短距離を求めているときの計算なので、
今までと同じ通り方
と
新しく追加したノードから行く通り方
のどちらがコストが小さいですか?という感じの内容なので、適当にマクロかなんか使って2つの整数の小さいほうを返すようなものをつくれば良いと思います。
#define min(x,y) ((x>y)?x:y)
みたいなやつね
あ、ちなみにcygwinについてきたgccというコンパイラを使っているので、C++のエラーは出ないときがあります
(C++用のコンパイラg++でもやってみたんですが、上手くいってしまいました)
最小値とか最大値とかを求めるのは標準の関数ではないはずなので、かなりまずいプログラムでしたorz
ご指摘ありがとうございました
また何かあったら言ってくださるとありがたいですm(_ _)m
さらに追記(すいませんorz)
どうやら、min・maxマクロはwindows.hの中で宣言されているようです(www2.ocn.ne.jp/~cbmaho/homepage/vc/
でも宣言されているならエラーは出ないはずなんだけどなぁ~・・・・・・
とりあえず!明日VisualStudioを使う予定があるので、学校で試してみたいと思います。
dijkstra
ダイクストラはかくかたりき
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#define BUTTON_START    0
#define BUTTON_RESET    1
#define BUTTON_MINEDGE  2
#define WINDOW_HEIGHT 450
#define WINDOW_WIDTH  450
#define NODE_NUM 30
#define NODE_R   7
POINT   node[NODE_NUM];
int  dmat[NODE_NUM][NODE_NUM]; 
int  is_edge[NODE_NUM][NODE_NUM]; 
int  min_edge[NODE_NUM][NODE_NUM];   
int  min_dist[NODE_NUM];       
int  start = 0;               
HBRUSH  first_color; 
HBRUSH  node_color;    
HPEN    edge_color;  
HPEN    me_color;     
void dijkstra(void)
{
    int done[NODE_NUM];
    int min, min_idx;
    int i, j, k, t;
    for (i = 0;i < NODE_NUM;i++)
        min_dist[i] = INT_MAX;
    min_dist[start] = 0;
    memset(done, 0, sizeof(done));
    memset(min_edge, 0, sizeof(min_edge));
    for (i = 1;i < NODE_NUM;i++) {
        min = INT_MAX;
        for (j = 0;j < NODE_NUM;j++) {
            if (!done[j] && min_dist[j] < min) {
                min = min_dist[j];
                min_idx = j;
            }
        }
        done[min_idx] = 1;
        for (k = 0;k < NODE_NUM;k++) {
            if (!done[k] && dmat[min_idx][k] != -1) {
                if (min_dist[k] > min_dist[min_idx]+dmat[min_idx][k]) {
                    for (t = 0;t < NODE_NUM;t++)
                        min_edge[k][t] = 0;
                    min_edge[k][min_idx] = 1;
                }
                min_dist[k] = min(min_dist[k], min_dist[min_idx]+dmat[min_idx][k]);
            }
        }
    }
}
int distance(int sx, int sy, int ex, int ey)
{
    int x2 = (sx-ex)*(sx-ex);
    int y2 = (sy-ey)*(sy-ey);
    return (int)sqrt(x2+y2);
}
void init_node(void)
{
    int i;
    for (i = 0;i < NODE_NUM;i++) {
        do {
            node[i].x = rand()%(WINDOW_HEIGHT-50)+20;
            node[i].y = rand()%(WINDOW_HEIGHT-50)+20;
        } while (node[i].x >= 360 && node[i].y <=70);
    }
}
void init_edge(void)
{
    int i, k, dist, cnt, rnd;
    int n = 10;
    memset(min_edge, 0, sizeof(min_edge));
    memset(is_edge, 0, sizeof(is_edge));
    for (i = 0;i < NODE_NUM;i++) {
        cnt = 0;
        for (k = 0;k < NODE_NUM;k++) {
            dist = distance(node[i].x, node[i].y, node[k].x, node[k].y);
            if (rand()%n==0 && dist < 250) {
                is_edge[i][k] = is_edge[k][i] = 1;
                cnt++;
            }
        }
        if (cnt == 0) {
            while ((rnd=rand()%NODE_NUM) == i)
                /* rnd != i になるまで回す */;
            is_edge[i][rnd] = is_edge[rnd][i] = 1;
        }
    }
}
void init_dmat(void)
{
    int i, k;
    memset(dmat, -1, sizeof(dmat));
    for (i = 0;i < NODE_NUM;i++)
        for (k = i+1;k < NODE_NUM;k++)
            if (is_edge[i][k] == 1)
                dmat[i][k] = dmat[k][i] = distance(node[i].x, node[i].y,node[k].x, node[k].y);
    for (i = 0;i < NODE_NUM;i++)
        dmat[i][i] = 0;
}
void init_pb(void)
{
    me_color    = CreatePen(PS_SOLID, 1, RGB(0xff, 0, 0));
    edge_color  = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
    first_color = CreateSolidBrush(RGB(0xff, 0, 0));
    node_color  = CreateSolidBrush(RGB(0xff, 0xff, 0xff));
}
void delete_pb(void)
{
    DeleteObject(me_color);
    DeleteObject(edge_color);
    DeleteObject(first_color);
    DeleteObject(node_color);
}
void DrawLine(HDC hdc, int xs, int ys, int xe, int ye)
{
    MoveToEx(hdc, xs, ys, NULL);
    LineTo(hdc, xe, ye);
    MoveToEx(hdc, 0, 0, NULL);
}
void DrawCircle(HDC hdc, int x, int y)
{
    Ellipse(hdc, x-NODE_R, y-NODE_R, x+NODE_R, y+NODE_R);
}
void Draw_Node(HDC hdc)
{
    int i;
    SelectObject(hdc ,edge_color);
    SelectObject(hdc ,first_color);
    DrawCircle(hdc, node[start].x, node[start].y);
    SelectObject(hdc , node_color);
    for (i = 0;i < NODE_NUM;i++)
        if (i != start)
            DrawCircle(hdc, node[i].x, node[i].y);
}
void Draw_Edge(HDC hdc)
{
    int i, k;
    SelectObject(hdc, edge_color);
    for (i = 0;i < NODE_NUM;i++) {
        for (k = i+1;k < NODE_NUM;k++) {
            if (is_edge[i][k]) {
                DrawLine(hdc, node[i].x, node[i].y, node[k].x, node[k].y);
            }
        }
    }
}
void Draw_MinEdge(HDC hdc)
{
    int i, k;
    SelectObject(hdc, me_color);
    for (i = 0;i < NODE_NUM;i++) {
        for (k = 0;k < NODE_NUM;k++) {
            if (min_edge[i][k])
                DrawLine(hdc, node[i].x, node[i].y, node[k].x, node[k].y);  
        }
    }
}
int SearchNode(POINT pt)
{
    int x = pt.x;
    int y = pt.y;
    int i;
    for (i = 0;i < NODE_NUM;i++) {
        if (i == start)
            continue;
        if (node[i].x-NODE_R <= x && x <= node[i].x+NODE_R &&
            node[i].y-NODE_R <= y && y <= node[i].y+NODE_R) {
                start = i;
                return 1;
        }
    }
    return 0;
}
void output_data(void)
{
    FILE *fp;
    int i, k;
    fp = fopen("result.txt", "w");
    fprintf(fp, "ノード\n");
    for (i = 0;i < NODE_NUM;i++)
        fprintf(fp, "%2d: (x,y) = (%3ld, %3ld)\n", i, node[i].x, node[i].y);
    fprintf(fp, "辺があるか\n");
    for (i = 0;i < NODE_NUM;i++) {
        for (k = 0;k < NODE_NUM;k++)
            fprintf(fp, "%d ", is_edge[i][k]);
        fprintf(fp, "\n");
    }
    fprintf(fp, "距離行列\n");
    for (i = 0;i < NODE_NUM;i++) {
        for (k = 0;k < NODE_NUM;k++)
            fprintf(fp, "%3d ", dmat[i][k]);
        fprintf(fp, "\n");
    }
    fprintf(fp, "最短距離に関わる辺\n");
    for (i = 0;i < NODE_NUM;i++) {
        for (k = 0;k < NODE_NUM;k++)
            fprintf(fp,"%d ", min_edge[i][k]);
        fprintf(fp, "\n");
    }
    fprintf(fp, "最短距離\n");
    for (i = 0;i < NODE_NUM;i++)
        fprintf(fp, "%d %d\n", i,min_dist[i]);
}
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp)
{
    HDC hdc;
    PAINTSTRUCT ps;
    POINT pt;
    static int visible_edge = 1;
    switch (msg) {
        case WM_CREATE:
            srand((unsigned int)time(NULL));
            init_node();
            init_edge();
            init_dmat();
            init_pb();
            return 0;
        case WM_DESTROY:
            delete_pb();
            PostQuitMessage(0);
            return 0;
        case WM_COMMAND:
            switch (LOWORD(wp)) {
                case BUTTON_START:
                    dijkstra();
                    InvalidateRect(hwnd,NULL,TRUE);
                    break;
                case BUTTON_RESET:
                    init_node();
                    init_edge();
                    init_dmat();
                    visible_edge = 1;
                    InvalidateRect(hwnd,NULL,TRUE);
                    break;
                case BUTTON_MINEDGE:
                    visible_edge = (visible_edge == 1) ? 0 : 1;
                    InvalidateRect(hwnd,NULL,TRUE);
                    break;
            }
        case WM_LBUTTONDOWN:
            pt.x = LOWORD(lp);
            pt.y = HIWORD(lp);
            if (SearchNode(pt))
                    InvalidateRect(hwnd,NULL,TRUE);
            break;
        case WM_PAINT:
            hdc = BeginPaint(hwnd , &ps);
            Draw_Node(hdc);
            if (visible_edge)
                Draw_Edge(hdc);
            Draw_MinEdge(hdc);
            EndPaint(hwnd , &ps);
            return 0;
    }
    return DefWindowProc(hwnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR lpCmdLine, int nCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS winc;
    winc.style    = CS_HREDRAW | CS_VREDRAW;
    winc.lpfnWndProc    = WndProc;
    winc.cbClsExtra     = 0;
    winc.cbWndExtra  = 0;
    winc.hInstance   = hInstance;
    winc.hIcon    = LoadIcon(NULL, IDI_APPLICATION);
    winc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    winc.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    winc.lpszMenuName   = NULL;
    winc.lpszClassName  = TEXT("TEST");
    if (!RegisterClass(&winc))
        return -1;
    hwnd = CreateWindow(
        TEXT("TEST"), TEXT("Dijkstra"),
        (WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX) | WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT,
        WINDOW_WIDTH+9, WINDOW_HEIGHT+35,
        NULL, NULL, hInstance, NULL
    );
    if (hwnd == NULL)
        return -1;
    CreateWindow(
        TEXT("BUTTON") , TEXT("Start") ,
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
        WINDOW_WIDTH-80 , 2 , 80 , 23 ,
        hwnd , (HMENU)BUTTON_START , hInstance , NULL
    );
    CreateWindow(
        TEXT("BUTTON") , TEXT("Reset") ,
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
        WINDOW_WIDTH-80 , 27 , 80 , 23 ,
        hwnd , (HMENU)BUTTON_RESET , hInstance , NULL
    );
    CreateWindow(
        TEXT("BUTTON") , TEXT("Min edge") ,
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
        WINDOW_WIDTH-80 , 52 , 80 , 23 ,
        hwnd , (HMENU)BUTTON_MINEDGE , hInstance , NULL
    );
    while (GetMessage(&msg, NULL, 0, 0))
        DispatchMessage(&msg);
    return msg.wParam;
}
ミスターブシドー
ガンダム見終わりました。
相変わらずグラハm・・・じゃなくってミスターブシドーが出てくるたびに噴き出しそうになる。
ちょこっとずつ人物のディテールが出てきた感じがあるNE!!
バーローとクジョウは知り合いだったようですはい。

すっげーぼやけてるけど、こないだゲーセンのプライズでとったらしいナイトガンダム載せとこう。
自分はゲーセンに一切行かない人間なのですが、知り合いにゲーセン好きが居て、時々くれます(要らない物もね)
そこそこでっかいので、適当にプラモのよこに飾っておこうと思う
わたぁしぃぃだよぉぉぉ!
 ブログネタ:クリスマスまでに恋人欲しい?
 参加中
 ブログネタ:クリスマスまでに恋人欲しい?
 参加中題名で元ねたがわかる方は、ジョジョをご存知の方でしょう
クリスマスまでに恋人が欲しいかどーかって話なんですが。
そりゃ欲しいですよもう!
正直です。
でもどうせ途中で面倒くさくなっちゃうんだよなぁ~
高校の時はメールするのが面倒になって自然消滅していました(苦笑)
今の状態はあるいみで自分の好き勝手にできる時間が多いからいいのかなぁ~
ないものねだりってことですわ