正文

关于简谐振动的演示2006-03-19 23:05:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/vfdff/11188.html

分享到:

#include <graphics.h>
#include <math.h>
#include <dos.h>
#include <malloc.h>
#include <string.h>
#define TIMEINTR 0x1c
#define MARGIN 4
#define BUTTONNUM 2
#define SCROLLBUTTONNUM 1
#define PI 3.1415926535
#define SB_WIDTH  20
#define SB_LENGTH 60
typedef enum bool {false, true}bool;
typedef enum state {OFF = 1, ON}State;
typedef enum mode {UP = 2, DOWN = 1};
typedef struct {
        int x,oldx;
        int y,oldy;
        int but;
} MOUSE;
typedef struct movement
{
    double A, W, Angle;
    double (*Coordinate)(double Time, struct movement *p);
}MOVE;

typedef struct button
{
    int x,y;
    char *contents;
    void (*Show)(struct button *p, int mode);
    bool (*Clicked)(struct button *p);
    void (*Function)();
}BUTTON;

typedef struct scrollbutton
{
    int x, y;
    char *contents;
    int place;
    bool (*Clicked)(struct scrollbutton *p);
    void (*Show)(struct button *p);
    int (*Function)(struct button *p);
}SCROLLBUTTON;

/************************declaration***********************/
double CDValue(double, MOVE *);
void show(BUTTON *p, State mode);
bool CheckClicked(BUTTON *p);
void interrupt( *oldhandler)(void);
bool MouseControl();
void Reset();
bool SCheckClicked(SCROLLBUTTON *p);
int MoveBar();
void SB_show(SCROLLBUTTON *p);
void FullScreenPROC();
void G_InitInterface();
/***********************global*****************************/
MOVE Movement[2] = {
                3,3,2,CDValue,
                2,1,4,CDValue,
                };
BUTTON Button[] = {
                320,370, "Full Screen",show, CheckClicked,FullScreenPROC,
                320,400, "Reset",show,CheckClicked,Reset,
                };
SCROLLBUTTON SButton[] = {
                            20,300, "speed", 50, SCheckClicked, SB_show, MoveBar,
                        };
double TIME = 0.0;
bool PROC = 1;
int SPEED = 100;
int Radius = 0;
bool IsFullScreen = false;
int count = 0;
int SW_X[2] = {80, 80}, SW_Y[2] = {80, 170};
void * mouse_buf;
MOUSE mouse;
unsigned Cursor[][16]=
{
     0x0000,      /*  0000000000000000   */
     0x4000,      /*  0100000000000000   */
     0x6000,      /*  0110000000000000   */
     0x7000,      /*  0111000000000000   */
     0x7800,      /*  0111100000000000   */
     0x7C00,      /*  0111110000000000   */
     0x7E00,      /*  0111111000000000   */
     0x7F00,      /*  0111111100000000   */
     0x7F80,      /*  0111111110000000   */
     0x7FC0,      /*  0111111111000000   */
     0x6C00,      /*  0110110000000000   */
     0x4600,      /*  0100011000000000   */
     0x0600,      /*  0000011000000000   */
     0x0300,      /*  0000001100000000   */
     0x0300,      /*  0000001100000000   */
     0x0180       /*  0000000110000000   */
};



/**********************************************************/
double CDValue(double Time,MOVE *p)
{

    return (p->A) * cos( (p->W) * Time + p->Angle);
}


void Set_x_range(int min, int max)
{
    union REGS ireg;

    ireg.x.ax = 7;
    ireg.x.cx = min;
    ireg.x.dx = max;
    int86(0x33, &ireg, &ireg);
}

int Which_pressed(MOUSE *mouse)
{
    union REGS ireg, oreg;

    ireg.x.ax = 3;
    int86(0x33, &ireg, &oreg);
    return(oreg.x.bx);
}

void Get_xy(MOUSE *grmouse)
{
    union REGS ireg, oreg;

    ireg.x.ax = 3;
    int86(0x33, &ireg, &oreg);

    grmouse->x = oreg.x.cx;
    grmouse->y = oreg.x.dx;
}

void Set_xy(int x, int y)
{
    union REGS ireg;

    ireg.x.ax = 4;
    ireg.x.cx = x;
    ireg.x.dx = y;
    int86(0x33, &ireg, &ireg);
}

void G_DrawMouse(int X, int Y)
{
    int t, i, j, x,y, color = BLACK;
    unsigned int token;
    y = Y;
    for(j = 0; j < 16; j++)
    {
        x = X;
        token = 0x8000;
        for(t = 0;t < 10; t++)
        {
        if( (Cursor[0][j] & token) != 0)
        {
            putpixel(x, y, color);
        }
        x++;
        token /= 2;
        }
        y++;
     }

}

void InitGraphicsBuf(int x,int y,int xx,int yy,void **p)
{
    *p=malloc(imagesize(x,y,xx,yy));
}

void ResumeGraphics(int x,int y,void *p)
{
    putimage(x,y,p,COPY_PUT);
}

bool GetBuf(int x,int y,int xx,int yy,void *p)   /*给图形指针赋值*/
{
    if(!p)return 0;
    getimage(x,y,xx,yy,p);
    return 1;
}

bool MouseControl()
{
    static int FIRST = 0;

    if(!FIRST)
    {
        Get_xy(&mouse);
        mouse.oldx = mouse.x;
        mouse.oldy = mouse.y;
        GetBuf(mouse.oldx,mouse.oldy,mouse.oldx+10,mouse.oldy+16,mouse_buf);
        G_DrawMouse(mouse.x, mouse.y);
        FIRST = 1;
    }
    mouse.but = Which_pressed(&mouse);
    if(!mouse.but)
    {
        Get_xy(&mouse);
        if(mouse.x != mouse.oldx | mouse.y != mouse.oldy)
        {
            ResumeGraphics(mouse.oldx, mouse.oldy, mouse_buf);
            mouse.oldx = mouse.x;
            mouse.oldy = mouse.y;
            GetBuf(mouse.x, mouse.y, mouse.x + 10, mouse.y + 16, mouse_buf);
            G_DrawMouse(mouse.x, mouse.y);
            return 1;
        }
        else return 0;
    }
    else
    {
        Set_xy(mouse.oldx,mouse.oldy);
        return 1;
    }
}

void CreateREC(int x, int y ,int X, int Y, int mode)
{
    int color1,color2;
    if(mode == 1){ color1 = DARKGRAY;color2 = WHITE;}
    if(mode == 2){ color1 = WHITE;color2 = DARKGRAY;}
    setfillstyle(1, LIGHTGRAY);
    bar(x, y, X, Y);
    setcolor(color1);
    line(x,y,X,y);
    line(x,y,x,Y);
    setcolor(color2);
    line(x,Y,X,Y);
    line(X,y,X,Y);

}

void G_SubWindow(int x, int y, int mode)
{
    CreateREC(x - 5, y - 5, x + 75, y + 75, 1);
    setfillstyle(1,BLACK);
    bar(x, y, x + 70, y + 70);
    line(x + 35, y, x + 35, y + 70);
    line(x, y + 35, x + 70, y + 35);
    if(mode = 1)
        circle(x + 35, y + 35, 30);
    if(mode = 2)
        {
            line(x + 35, y, x + 35, y + 70);
            line(x, y + 35, x + 70, y + 35);
        }
}

void G_MovementFace()
{
    CreateREC(295, 145, 505, 355, 1);
    setfillstyle(1,BLACK);
    bar(300,150,500,350);
    setcolor(WHITE);
    line(400,150,400,350);
    line(300,250,500,250);
}

double MaxA()
{
    return Movement[0].A > Movement[1].A ? Movement[0].A : Movement[1].A;
}

void G_MovementShow(double Time)
{
    double X = Movement[0].Coordinate(Time, Movement);
    double Y = Movement[1].Coordinate(Time, Movement+1);
    X = 400 + X * 90 / MaxA();
    Y = 250 - Y * 90 / MaxA();
    setcolor(WHITE);
    circle(X,Y,Radius);
    setfillstyle(1,WHITE);
    floodfill(X,Y,WHITE);
}

void show(BUTTON *p, State mode)
{
    if(mode != ON && mode != OFF) return;
    CreateREC(p->x, p->y, p->x + strlen(p->contents)*8+ MARGIN, p->y + 8 + MARGIN*3, mode);
    setcolor(BLUE);
    outtextxy(p->x + MARGIN, p->y + MARGIN * 2, p->contents);
}
bool CheckClicked(BUTTON *p)
{
    return mouse.x>p->x && mouse.x<p->x + strlen(p->contents) * 8 + MARGIN && mouse.y>p->y && mouse.y<p->y + 8 + MARGIN*2 && mouse.but;
}

bool SCheckClicked(SCROLLBUTTON *p)
{
    int x = p->x + strlen(p->contents) * 8 + 3;
    return mouse.x > x && mouse.x < x + SB_LENGTH + 3 && mouse.y > p->y && mouse.y < p->y +SB_WIDTH && mouse.but;
}

void Reset()
{
    G_MovementFace();
    G_SubWindow(SW_X[0],SW_Y[0],1);
    G_SubWindow(SW_X[1],SW_Y[1],1);
    TIME = 0.0;
}


int SetValue(int i, int place)
{
    if(place < 0) place = 0;
    switch(i)
    {
        case 0: SPEED = (double)(SB_LENGTH - 10 - place) / (SB_LENGTH - 10)* 1000;
    }
}
void FullScreenShow(double n)
{
    double X = Movement[0].Coordinate(n, Movement);
    double Y = Movement[1].Coordinate(n, Movement+1);
    X = 320 + X * 200 / MaxA();
    Y = 240 - Y * 200 / MaxA();
    setcolor(WHITE);
    circle(X,Y,Radius + 2);
    setfillstyle(1,WHITE);
    floodfill(X,Y,WHITE);
}

void FullScreenPROC()
{
    double n;
    int IsFullScreen = 1;
    cleardevice();
    setcolor(WHITE);
    line(0, 240, 639, 240);
    line(320, 0, 320, 479);
    for(n = 0; n <= TIME; n += 0.005)
        FullScreenShow(n);
    while(IsFullScreen)
    {
        if( bioskey(1) ){ getch();IsFullScreen = 0;}
        TIME += 0.005;
        FullScreenShow(TIME);
        delay(SPEED);
    }
    G_InitInterface();
    for(n = 0; n <= TIME; n+= 0.01)
        G_MovementShow(n);
}

void G_AddButton()
{
    int i;
    for(i = 0; i < BUTTONNUM; i++)
        Button[i].Show(Button + i, ON);
    for(i = 0; i < SCROLLBUTTONNUM; i++)
        SButton[i].Show(SButton + i);
}


void G_Bar(SCROLLBUTTON *p, int place)
{
    int tx = p->x + strlen(p->contents) * 8 + 3;
    CreateREC(tx + place, p->y + 2, tx + place + 10, p->y + 18,UP);
}

void SB_show(SCROLLBUTTON *p)
{
    int tx = p->x + strlen(p->contents) * 8 + 2;
    setfillstyle(1,LIGHTGRAY);                        /* first clear the screen */
    bar(tx, p->y, tx + SB_WIDTH, p->y + SB_LENGTH);
    outtextxy(p->x, p->y + SB_WIDTH /2 - 4, p->contents);
    setcolor(BLACK);
    line(tx, p->y + SB_WIDTH / 2 - 3, tx, p->y + SB_WIDTH / 2 + 3);
    line(tx + SB_LENGTH , p->y + SB_WIDTH / 2 - 3, tx + SB_LENGTH, p->y + SB_WIDTH / 2 + 3);
    line(tx, p->y + SB_WIDTH / 2, tx +SB_LENGTH , p->y + SB_WIDTH / 2);
    G_Bar(p, p->place);
}

int MoveBar(SCROLLBUTTON *p)
{
    int tx = p->x + strlen(p->contents) * 8, oldx,oldy,token = 0;
    rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);
    oldx = tx + 3 + p->place;
    ResumeGraphics(mouse.oldx, mouse.oldy, mouse_buf);
    if(mouse.x > tx + 3 + p->place && mouse.x < tx + 3 + p->place + 10 && mouse.y > p->y + 2 && mouse.y < p->y + 18)
    {
        while(Which_pressed(&mouse) )
        {
            if(mouse.x != oldx && mouse.x > tx + 2 && mouse.x < tx + 3 + SB_LENGTH - 10 )
            {
                ResumeGraphics(oldx, mouse.y, mouse_buf);
                setfillstyle(1, LIGHTGRAY);                      /* clear first */
                bar(tx + 3 + p->place, p->y +2, tx + 3 + p->place + 10, p->y + 18);
                p->place = mouse.x - tx - 3;
                setcolor(BLACK);
                line(tx + 2, p->y + SB_WIDTH / 2 - 3, tx + 2, p->y + SB_WIDTH / 2 + 3);
                line(tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 - 3, tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 + 3);
                line(tx + 2, p->y + SB_WIDTH / 2, tx + 2 +SB_LENGTH , p->y + SB_WIDTH / 2);
                G_Bar(p, p->place);
                setcolor(WHITE);
                rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);
                GetBuf(mouse.x, mouse.y, mouse.x + 10, mouse.y +16, mouse_buf);
                G_DrawMouse(mouse.x, mouse.y);
                oldx = mouse.x;
                token  = 1;
            }
            oldy = mouse.y;
            Get_xy(&mouse);
            mouse.y = oldy;

        }
        if(token){ResumeGraphics(oldx, mouse.y, mouse_buf);token = 0;}
    }
    else if(SCheckClicked(p) )
    {
        if(mouse.x <= tx + SB_LENGTH - 8){
        setfillstyle(1, LIGHTGRAY);
        bar(tx + 3 + p->place, p->y +2, tx + 3 + p->place + 10, p->y + 18);
        p->place = mouse.x - tx - 3;
        if(p->place > tx + SB_LENGTH - 12)p->place = tx + SB_LENGTH - 12;
        setcolor(BLACK);
        line(tx + 2, p->y + SB_WIDTH / 2 - 3, tx + 2, p->y + SB_WIDTH / 2 + 3);
        line(tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 - 3, tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 + 3);
        line(tx + 2, p->y + SB_WIDTH / 2, tx + 2 +SB_LENGTH, p->y + SB_WIDTH / 2);
        G_Bar(p, p->place);
        setcolor(WHITE);
        rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);

    }
    }
    setcolor(LIGHTGRAY);
    rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);
    GetBuf(mouse.x, mouse.y, mouse.x + 10, mouse.y +16, mouse_buf);
    mouse.oldx = mouse.x, mouse.oldy = mouse.y;
    return p->place;
}

void SubWindowShow()
{
    int x,y,i,Token = 0;
    for(i = 0;i < 2; i++)
    {
        if(Token)
        {
            setcolor(WHITE);
            line(SW_X[i] + 35, SW_Y[i], SW_X[i] + 35, SW_Y[i] + 70);
            line(SW_X[i], SW_Y[i] + 35, SW_X[i] + 70, SW_Y[i] + 35);
            Token = 0;
        }
        if(TIME)
        {
            TIME -= 0.01;
            x = 30 * cos( (TIME * Movement[i].W + Movement[i].Angle) );
            y = 30 * sin( (TIME * Movement[i].W + Movement[i].Angle) );
            setcolor(BLACK);
            if(x && y)
            line(SW_X[i] + 35, SW_Y[i] + 35, SW_X[i] + 35 + x, SW_Y[i] + 35 + y);
            circle(SW_X[i] + 35 + x, SW_Y[i] + 35 + y, 2);
            TIME += 0.01;
        }
        x = 30 * cos( (TIME * Movement[i].W + Movement[i].Angle) );
        y = 30 * sin( (TIME * Movement[i].W + Movement[i].Angle) );
        setcolor(YELLOW);
        line(SW_X[i] + 35, SW_Y[i] + 35, SW_X[i] + 35 + x, SW_Y[i] + 35 + y);
        circle(SW_X[i] + 35 + x, SW_Y[i] + 35 + y, 2);
        setfillstyle(1,BLACK);
        floodfill(SW_X[i] + 35 + x, SW_Y[i] + 35 + y, YELLOW);
        circle(SW_X[i] + 35, SW_Y[i] + 35, 30);
        if(!(x && y))
        {
            setcolor(WHITE);
            line(SW_X[i] + 35, SW_Y[i], SW_X[i] + 35, SW_Y[i] + 70);
            line(SW_X[i], SW_Y[i] + 35, SW_X[i] + 70, SW_Y[i] + 35);
            Token = 1;
        }

    }
}

bool init()
{
    int driver = VGA, drivermode = VGAHI;
    initgraph(&driver, &drivermode, "");
    if(graphresult() != 0)
        {
            printf("can't initgraph");
            return false;
        }
    InitGraphicsBuf(0,0,10,16,&mouse_buf);
    cleardevice();
    return true;
}
void G_InitInterface()
{
    setfillstyle(1,LIGHTGRAY);
    bar(0,0,639,479);
    G_MovementFace();
    G_SubWindow(SW_X[0],SW_Y[0],1);
    G_SubWindow(SW_X[1],SW_Y[1],1);
    G_AddButton();
}

main()
{
    int i;
    init();
    G_InitInterface();
    while(PROC)
        {
            if(bioskey(1))PROC = false;
            for(i = 0; i< BUTTONNUM; i++)
                if(Button[i].Clicked(Button + i))
                {
                    Button[i].Show(Button + i, OFF);
                    delay(10000);
                    Button[i].Show(Button + i, ON);
                    Button[i].Function();
                    break;
                }
            for(i = 0; i< SCROLLBUTTONNUM; i++)
                if(SButton[i].Clicked(SButton + i) )
                    {
                        SetValue(i, SButton[i].Function(SButton + i) );
                        break;
                    }
            MouseControl();
            SubWindowShow();
            G_MovementShow(TIME);
            TIME+=0.01;
            delay(SPEED);
        }
    closegraph();
}

阅读(3493) | 评论(1)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册