DXライブラリ,楕円を回転して描画

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
田中

DXライブラリ,楕円を回転して描画

#1

投稿記事 by 田中 » 12年前

こんにちは.
1つ質問させて下さい.

楕円を回転させて描画したいのですが,
DXライブラリを用いた場合どうすれば良いでしょうか?

楕円を回転させた状態というのは,
楕円の短軸,長軸がX軸,Y軸と平行でない状態のことを言ってます.
ちなみに2次元の話で大丈夫です.

よろしくお願い致します.

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ,楕円を回転して描画

#2

投稿記事 by みけCAT » 12年前

少なくとも、シェーダーを使えば可能なようです。

main.cpp

コード:

#include <DxLib.h>
#include <cmath>

char Key[256];

/*
(cx,cy)を中心にangle==0の時のx方向の半径rx、y方向の半径ryの楕円をcolorで描画する。
angleは右回り(時計回り)を正とし、ラジアンで表す。
*/
int DrawOval2(int cx,int cy,int rx,int ry,int color,float angle) {
	float x1,y1,x2,y2,x3,y3,x4,y4;
	float sine,cosine;
	// 楕円が入る長方形の四隅の座標を計算する
	if(rx<0)rx=-rx;
	if(ry<0)ry=-ry;
	sine=sin(angle);
	cosine=cos(angle);
	x3=cosine*rx-sine*ry;
	y3=sine*rx+cosine*ry;
	x2=cosine*rx-sine*(-ry);
	y2=sine*rx+cosine*(-ry);
	x1=-x3;y1=-y3;
	x4=-x2;y4=-y2;
	x1+=cx;y1+=cy;x2+=cx;y2+=cy;
	x3+=cx;y3+=cy;x4+=cx;y4+=cy;
	// シェーダーのパラメータを設定
	static int shader=-1;
	VERTEX2DSHADER vert[6]={};
	FLOAT4 col;
	int r,g,b;
	vert[0].pos=VGet(x1,y1,0.0f);
	vert[0].rhw=1.0f;
	vert[0].u=0.0f;
	vert[0].v=0.0f;
	vert[1].pos=VGet(x2,y2,0.0f);
	vert[1].rhw=1.0f;
	vert[1].u=1.0f;
	vert[1].v=0.0f;
	vert[2].pos=VGet(x3,y3,0.0f);
	vert[2].rhw=1.0f;
	vert[2].u=1.0f;
	vert[2].v=1.0f;
	vert[3].pos=VGet(x1,y1,0.0f);
	vert[3].rhw=1.0f;
	vert[3].u=0.0f;
	vert[3].v=0.0f;
	vert[4].pos=VGet(x3,y3,0.0f);
	vert[4].rhw=1.0f;
	vert[4].u=1.0f;
	vert[4].v=1.0f;
	vert[5].pos=VGet(x4,y4,0.0f);
	vert[5].rhw=1.0f;
	vert[5].u=0.0f;
	vert[5].v=1.0f;
	GetColor2(color,&r,&g,&b);
	if(shader==-1)shader=LoadPixelShader("circle.pso");
	SetUsePixelShader(shader);
	col.x=r/255.0f;
	col.y=g/255.0f;
	col.z=b/255.0f;
	SetPSConstF(10,col);
	// 描画する
	DrawPolygon2DToShader(vert,2);
	// エラーチェックは省略
	return 0;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
	SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定

	int clWhite=GetColor(255,255,255);

	int cx=320,cy=240;
	int angle=0;
	int rx=100,ry=50;

	while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
		//↑メッセージ処理         ↑画面をクリア          ↑キーボード入力状態取得       ↑ESCが押されていない

		//ココに処理を書いていく
		if(Key[KEY_INPUT_A] && rx-3>0)rx-=3;
		if(Key[KEY_INPUT_Q])rx+=3;
		if(Key[KEY_INPUT_S] && ry-3>0)ry-=3;
		if(Key[KEY_INPUT_W])ry+=3;
		if(Key[KEY_INPUT_D])angle-=3;
		if(Key[KEY_INPUT_E])angle+=3;
		if(angle<0)angle+=360;
		if(angle>=360)angle-=360;

		DrawOval2(cx,cy,rx,ry,GetColor(0,255,0),angle*DX_PI_F/180.0f);

		DrawString(10,10,               "            ↓ ↑",clWhite); 
		DrawFormatString(10, 40,clWhite,"   rx %5d A  Q",rx);
		DrawFormatString(10, 70,clWhite,"   ry %5d S  W",ry);
		DrawFormatString(10,100,clWhite,"angle %5d D  E",angle);

		ScreenFlip();//裏画面を表画面に反映
	}

	DxLib_End();
	return 0;
}
circle.fx

コード:

struct PS_INPUT {
	float4 DiffuseColor		: COLOR0;
	float4 SpecularColor	: COLOR1;
	float2 TextureCoord0	: TEXCOORD0;
	float2 TextureCoord1	: TEXCOORD1;
};

struct PS_OUTPUT {
	float4 Output			: COLOR0;
};

float4 color : register(c10);
sampler DiffuseMapTexture : register(s0);

PS_OUTPUT main(PS_INPUT PSInput) {
	PS_OUTPUT PSOutput;

	PSOutput.Output.r=color.r;
	PSOutput.Output.g=color.g;
	PSOutput.Output.b=color.b;
	// 円を描画
	if((PSInput.TextureCoord0.x-0.5f)*(PSInput.TextureCoord0.x-0.5f)+
			(PSInput.TextureCoord0.y-0.5f)*(PSInput.TextureCoord0.y-0.5f)<=0.25f) {
		PSOutput.Output.a=1.0f;
	} else {
		PSOutput.Output.a=0.0f;
	}

	return PSOutput;
}
circle.fxはピクセルシェーダーとしてコンパイルし、
circle.psoというファイル名でexeファイルのカレントディレクトリに保存してください。

プロジェクト(ソースコードを含む)とバイナリ一式を添付します。
添付ファイル
shader_daen.zip
回転した楕円を描画するテスト
(1.58 MiB) ダウンロード数: 158 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

田中

Re: DXライブラリ,楕円を回転して描画

#3

投稿記事 by 田中 » 12年前

みけCAT先生

本当にありがとうございます.
私の作成しているプログラムにも組み込むことが出来そうです.

ちなみになんですけど,
楕円を線だけで表示することは出来ますでしょうか??
(現在塗りつぶしになっているのですが,可能でしたら線で表示したいです.線の太さも指定できると最高です(> <)

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ,楕円を回転して描画

#4

投稿記事 by みけCAT » 12年前

線だけでしたら、細かく分割して描画するのがいいと思います。

コード:

#include <DxLib.h>
#include <cmath>

char Key[256];

/*
(cx,cy)を中心にangle==0の時のx方向の半径rx、y方向の半径ryの楕円をcolorで描画する。
angleは右回り(時計回り)を正とし、ラジアンで表す。
*/
int DrawOval2(int cx,int cy,int rx,int ry,int color,float angle,int thickness=1) {
	float sine,cosine;
	const int BUNKATU=512;
	float px,py;
	sine=sin(angle);
	cosine=cos(angle);
	px=cosine*rx;py=sine*rx;
	if(rx<0)rx=-rx;
	if(ry<0)ry=-ry;
	for(int i=1;i<=BUNKATU;i++) {
		float nowangle=i*2.0*DX_PI_F/BUNKATU;
		float rawx,rawy;
		float x,y;
		rawx=rx*cos(nowangle);
		rawy=ry*sin(nowangle);
		x=cosine*rawx-sine*rawy;
		y=sine*rawx+cosine*rawy;
		DrawLine(cx+(int)px,cy+(int)py,cx+(int)x,cy+(int)y,color,thickness);
		px=x;py=y;
	}
	// エラーチェック省略
	return 0;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
	SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定

	int clWhite=GetColor(255,255,255);

	int cx=320,cy=240;
	int angle=0;
	int rx=100,ry=50;
	int thick=1;

	while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
		//↑メッセージ処理         ↑画面をクリア          ↑キーボード入力状態取得       ↑ESCが押されていない

		//ココに処理を書いていく
		if(Key[KEY_INPUT_A] && rx-3>0)rx-=3;
		if(Key[KEY_INPUT_Q])rx+=3;
		if(Key[KEY_INPUT_S] && ry-3>0)ry-=3;
		if(Key[KEY_INPUT_W])ry+=3;
		if(Key[KEY_INPUT_D])angle-=3;
		if(Key[KEY_INPUT_E])angle+=3;
		if(Key[KEY_INPUT_F] && thick>1)thick--;
		if(Key[KEY_INPUT_R])thick++;
		if(angle<0)angle+=360;
		if(angle>=360)angle-=360;

		DrawOval2(cx,cy,rx,ry,GetColor(0,255,0),angle*DX_PI_F/180.0f,thick);

		DrawString(10,10,               "            ↓ ↑",clWhite); 
		DrawFormatString(10, 40,clWhite,"   rx %5d A  Q",rx);
		DrawFormatString(10, 70,clWhite,"   ry %5d S  W",ry);
		DrawFormatString(10,100,clWhite,"angle %5d D  E",angle);
		DrawFormatString(10,130,clWhite,"thick %5d F  R",thick);

		ScreenFlip();//裏画面を表画面に反映
	}

	DxLib_End();
	return 0;
}
線の太さはとりあえず標準機能を使用してみましたが、今のところうまくいっていないようです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

田中

Re: DXライブラリ,楕円を回転して描画

#5

投稿記事 by 田中 » 12年前

猫CAT先生

無事にプログラムに組み込むことが出来ました.
ありがとうございました.

閉鎖

“C言語何でも質問掲示板” へ戻る