現在地 >> メニュー >> サンプルコード::OpenGL >> OpenGL::Bresenham

問題


Bresenhamのアルゴリズムを用いて、以下の2点を結ぶ直線をひけ

A(30,100)
B(200,250)

その他条件:
ウィンドウ座表系とあわせるためにgluOrtho2D()を使用する。

マウスでクリックすると、クリック位置が出力される。

答え


#include <cmath>
#include <iostream>
#include <GL/glut.h>


/****[データ構造の定義]******/
struct _POINT
{
int x,y;
};
typedef struct _POINT POINT;

POINT a ={30,100};
POINT b ={200,250};


/***[計算用パラメータ]***/
struct _PARAMETER
{
int dx,dy;
int a,a1,e;
int sx,sy;
int flag;
};
typedef struct _PARAMETER PARAM;

PARAM param;


/*********[プロトタイプ宣言]*************/
void display();
void reshape(int w, int h);
void mouse(int button, int state,int x, int y);

void CALC_DATA();
void DRAW_LINE(int flag);


using namespace std;


/******[OpenGLの初期設定]******************/
inline void GLUT_INIT()
{
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(400,400);
}


inline void GLUT_CALL_FUNC()
{
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
}

inline void MY_INIT()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
CALC_DATA();
}

int main(int argc, char *argv[])
{

glutInit(&argc,argv);
GLUT_INIT();

glutCreateWindow("window name");

GLUT_CALL_FUNC();
MY_INIT();
glutMainLoop();

return 0;
}


void display(void)
{
glColor3d(1,0,0);
DRAW_LINE(param.flag);
glFlush();
}

void reshape(int w, int h)
{
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,w,h,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}


void mouse(int button, int state,int x, int y)
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
printf("click at (%d,%d) \n", x,y);
}
}


/*******[ここから、各種関数]******************/

/* 2点から必要なデータを計算 */
void CALC_DATA()
{
param.dx = abs(a.x - b.x);
param.dy = abs(a.y - b.y);

a.x > b.x ? (param.sx = -1) : param.sx = 1;
a.y > b.y ? (param.sy = -1) : param.sy = 1;

if(param.dx >= param.dy)
{
param.a = 2 * param.dy;
param.a1 = param.a - (2 * param.dx);
param.e = param.a - param.dx;
param.flag = 0;
}else
{
param.a = 2 * param.dx;
param.a1 = param.a - (2 * param.dy);
param.e = param.a - param.dy;
param.flag = 1;
}
}


/* プレゼンハムで描画 */
void DRAW_LINE(int flag)
{
int x = a.x;
int y = a.y;
if(param.flag == 0)//xで走査
{
for(x = a.x ;(param.sx >=0 ? x<= b.x : x>=b.x);x+=param.sx)
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
if(param.e >= 0)
{
y += param.sy;
param.e+=param.a1;
}else
{
param.e+=param.a;
}
}
}else //yで走査
{
for(y = a.y; (param.sy >=0 ? y<= b.y : y>=b.y) ;y+=param.sy)
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
if (param.e>=0)
{
x+=param.sx;
param.e += param.a1;
}else
{
param.e+=param.a;
}
}
}
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます