• 締切済み

画像をクラスにどうやって渡すべきかが解りません

こんにちは、今回もC++のプログラミングについて質問させて頂きます。 現在勉強がてら作っている簡単なゲームで、処理を軽くするたびに画像ファイルを読み込む回数を減らそうとしています。、 プレイヤーのように最初から生成されているオブジェクトの場合はどうにか出来たのですが、プログラムの途中で生成するオブジェクトの場合、画像ファイルをどう読み込めば良いのか解らず困っています。 現在、炎の弾を作り出すメンバ関数 void Object::Shoot_FireBall(int Angle)//ファイアボール { FireBall* FireBall1 = new  FireBall(true,5,Ref_x(),Ref_y(),charge,"FIREBALL",Angle,5,0,40,40,4,true,Image_FireBall,1.0,true,true); if(Objects_Numbers>=Actions_Limit) { Objects_Numbers = Actions_Lower; delete Objects[Objects_Numbers]; } Objects[Objects_Numbers++] = FireBall1; } 上記のコードの FireBall(true,5,Ref_x(),Ref_y(),charge,"FIREBALL",Angle,5,0,40,40,4,true,Image_FireBall,1.0,true,true); の中の Image_FireBall をどこで定義すれば良いかが解らず困っています 以前までは void Player::Shoot_FireBall()//ファイアボール { FireBall* FireBall1 = new FireBall(5,Ref_x(),Ref_y(),charge,"FIREBALL",Ref_angle(),5,0,40,40,4,true,"Action/FireBall1.png",6,3,2,1.0,true,true); if(FIRE_num>=FIRE_Limit) FIRE_num = 1; FIRE_Array[FIRE_num++] = FireBall1; } といったように画像ファイルの名前を渡し、FireBallのコンストラクター内で画像を取得していたのですが、それでは処理が重くなると聞き、修正しようとしています。 最初は画像ファイルをメインループに入る前に読みこめば良いのかと思ったのですが、それでは有効範囲が違うので定義されていない識別子とコンパイラに認識され使用することが出来ません。 グローバル宣言を使えばなんとかなるとは思うのですが、グローバル宣言はあまり多用しない方が良いようなので、他の方法を考え現在はObjectクラスの基底クラスGraphの中で class Graph { public: protected: int *Image_FireBall; }; Graph::Graph(bool Sub_bShow,int sub_x,int sub_y,int XSize , int YSize, double Sub_ExtRate, double sub_Angle,int Sub_Trans_Flag,int Sub_Turn_Flag,int* sub_Image) { Image_FireBall = new int[6]; LoadDivGraph("Action/FireBall1.png", 6, 3 , 2 ,40 , 40 , Image_FireBall); } /* 関係の無いメンバやその初期化については省いて載せています */ のようにしていますが、コレでは結局FireBallオブジェクトが生成される度に読み込まれているので処理は変わらないと思い、他の方法を探している所です。 一体どうやって定義するのが良いのでしょうか、良い方法があれば教えて頂けると助かります、宜しくお願いします。

みんなの回答

回答No.5

あ、もうひとつありましたね。パターン3 (これが最善かも) 実際には異なるクラス名、コードで書いてもなんら構いませんが ここでは便宜上FireBallがObjectクラスの派生クラス、として説明します。 3.FireBall等のクラスがObjectクラスの派生クラスであるなら、Objectクラスが持てばいい Objectクラスが複数の派生クラスのために staticメンバを持ってしまえばいい可能性があります しかも、ほんのちょっとだけメモリを多く使うだけで 「配列で確保しておきながら」 「毎回インデックスの指定は必要ない」 といったことも可能です。 例) ////Object.h//// class Graph; class Object { protected: enum CLASS_ID { FIREBALL_ = 0, その他, NUM_ }; private: static Graph* graphlist[NUM_]; //privateでOK protected: const Graph* const graph; //真骨頂 その他諸々のデータや関数 Object( CLASS_ID ); //基底クラスのコンストラクタに上のenumの、IDを指定 virtual ~Object(); //デストラクタはやっぱり仮想で public: static void Class_Initialize(); static void Class_Cleanup(); }; で、ソースはこんな感じに Graph* Object::graphlist[NUM_]; Object::Object( CLASS_ID id ) : graph(graphlist[id]) {} //これが狙い Object::~Object(){} void Object::Class_Initialize(){ //下でtry-catchを使いたい場合は前準備 for ( int i = NUM_; i--; ) graphlist[i] = NULL; graphlist[FIREBALL_] = new Graph(FireBall用の引数リスト); graphlist[その他] = new Graph(その他用の引数リスト); } void Object::Class_Cleanup(){ //一括解放 for ( int i = NUM_; i--; ) delete graphlist[i]; } 継承時は ////FireBall.h//// #include "Object.h" class FireBall : public Object { 最小限のメンバで済む } となり、FireBallのコンストラクタでは FireBall::FireBall() : Object(FIREBALL_), その他FireBallのメンバを初期化 { } このように、基底クラスのコンストラクタを引数付きで明示的に呼び出せばいいです。 これなら描画時に void FireBall::Draw() const { graph->Draw(なんちゃら); } だけで出来てしまいます。 あとはアプリの初期化で Object::Class_Initialize(); 後始末で Object::Class_Cleanup(); とするだけでいいです。 もちろん、この手法で行って、尚且つ 数が0の時が長く出現する場合があり ずっと確保し続けていると都合が悪い、というような場合 で 尚且つ「FireBall等のオブジェクトの数が可変長」 がいいのであれば、staticメンバに「現在の各クラスのインスタンスの数」 を追加し コンストラクタで0→1になったら ロード 1→0になったらアンロード という風に(ただしそれにコストがかかる場合は状況次第なのでそこは調整する。) すれば、実用レベルの、ほぼ最高に近い形になると思います。 その場合は static void Class_Initialize(); static void Class_Cleanup(); といったメンバが、かわりに不要になります。

回答No.4

>1.Graphクラスにstaticメンバを持たせる ↓ >2.Graphクラスにstaticメンバを持たせる でしたねw 本題ではないので大丈夫だと思いますが。

回答No.3

どうも とりあえず >Objectクラスの基底クラスGraph これが文字通りの意味ならば、ちょっとお勧めできない気がします。 Objectクラス(一般的なオブジェクトの動作やデータをつかさどる基底クラスっぽい)とGraphクラスって、関係的に直交してそう(独立した概念)に感じるからです。っていうか、通常基底クラスの方が抽象的な名前になります。 お勧めな方法は Graphクラスは別のクラスとして作っておいて class Graph { LPCTSTR filename; int width, height; その他諸々のデータ public: データの描画や確保のための、最小限の各メンバ関数 }; とかにしておいて FireBallクラスはObjectクラスとかから継承して作り Graph クラスには「アクセスするだけ」とか ObjectクラスにGraphクラスのポインタとかをメンバとして持たせる の方が、自然に思います。 もひとつ Shoot_FireBall関数が呼ばれるたびに new と deleteが呼ばれる仕様になっていますが new や deleteは単なるメンバの書き換えと比べれば、遥かに重い処理であることがほとんどです。 なので、こいつをそのタイミングで毎度行うのであれば (つまり前回質問でのforループのように書くならば) 最初から決まった分配列確保しておくのは適切とは言えないはずだし 最初から決まった分配列確保しておくなら 毎回newやdeleteをするべきではなく、やはり必要なメンバをその都度書き変えるだけ、というのが定説になります。 そしたら、本題です。 画像読み込みに関してですが そんな時は 「static」が超お役立ちの可能性があります。 内部処理とかはグローバルといっても遜色ないような形になりますが コードの上では アクセス制御が出来るので遥かに容易いことになります。 ぱっと思いつくだけでも大きく分けて2パターンのアプローチがあります。 1.FireBallクラスなどにstaticメンバを持たせる Graphクラスを上のように別途作っておくとした場合 一例としては Objectクラスを継承したFireBallクラスに class Graph; class FireBall : public Object { static Graph* graph; void Draw() const override; ・ ・ ・ public: static void Class_Initialize(); static void Class_Cleanup(); }; とかにしといて ソースの方で #include "Graph.h" Graph* FireBall::graph( NULL ); void FireBall::Class_Initialize(){ graph = new Graph(引数のリスト); //ここで画像読み込み } void FireBall::Class_Cleanup(){ delete graph; //ここで画像のアンロードなどの解放処理 } void FireBall::Draw() const { graphを使った処理~ } という風にして置いたうえで アプリケーション開始時に FireBall::Class_Initialize(); をよびだし、終了時に FireBall::Class_Cleanup(); を呼び出す。 といった手法が考えられます。 この場合 Graph* graph; を直接いじれるのはFireBallクラスだけなわけですから どこからでも自由にアクセスされる恐れがある グローバル変数とは大違いで、しかも目的を達することができます。 1.Graphクラスにstaticメンバを持たせる staticを使うもう一つの方法は class Graph { LPCTSTR filename; int width, height; その他諸々のデータ public: enum { FIREBALL_ = 0, PLAYER1_, PLAYER2_, NUM_ }; private: static Graph* graph[NUM_]; //ココにポインタ配列 public: static const Graph* GetGraph( int i ){ //描画の時などにとりだす。 return graph[i]; } その他データの描画や確保のための、最小限の各メンバ関数諸々 static void Class_Initialize(); //この中でNUM_分graphにロードする static void Class_Cleanup(); //この中でNUM_分全て解放する }; このようにして置き 例えば FireBall側から const Graph* graph = Graph::GetGraph( Graph::FIREBALL_ ); graph->Draw(なんちゃら); このように呼び出す、といった方法もあります。 この場合もやはり、初期化(画像の読み込み)と解放 の処理は、どこかで行う必要があります。 こっちの場合は、クラスごとに読み込み関数を用意してやる必要がないかわりに Graph::FIREBALL_などのインデックスを指定して取り出してやる必要はあります。

回答No.2

同一クラスのオブジェクトで共通の画像データだとして: 画像データを静的メンバ変数にして、コンストラクタでロード済みはどうか 判定し、ロードされていない場合のみロードするようにする。 (最初のオブジェクト生成は時間がかかるが、次からは速い) 同一クラスのオブジェクトで複数の画像データだとして: 上記と同様に静的メンバを使用する。 ロード済の画像の名称を静的メンバ変数で管理する。 クラスで共通のデータを処理する場合、静的メンバ変数を使用するのが一般 的です。 後、画像データを静的メンバ変数にすれば、そのロード処理は静的メンバ関数 で実行できるのでプログラムの初期化に実行することも可能です。 まあ、ある意味シングルトンパターンと言えるでしょう。 静的メンバ変数/関数はある意味ではグローバルと言えるでしょうが、グローバル にすべき理由があって行うのであれば、無条件に忌避すべきものでもありません。 静的メンバをわかった上でのことならごめんなさい。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

static って知ってる?

関連するQ&A

  • クラス内で作成したクラスへのアクセス方法。

    こんにちは、C++のプログラミングについて質問させて頂きます。 現在クラスを使って簡単なゲームを作ってみようと勉強中なのですが、クラスの扱いについて質問があります。 void Object::FireBall() {    //初期化の内容は読まなくても大丈夫です。 Action FireBall = Action(10,Ref_x() + cos(angle * PI / 180.0f)*3,Ref_y() + cos(angle * PI / 180.0f) *3 ,5,100,40,40,4,true,"Action/FireBall1.png",6,3,2,1.0,Ref_angle(),true,false); } といったように、Objectクラス内でActionクラスを作成したとします。 このとき、メイン関数内でFireBallの各メンバにはどうやってアクセスすれば良いのでしょうか? Objectクラスのオブジェクトの名前がPlayer[1]だとしたとき、 Player[1]->FireBall.Draw_Graph() のようにやるのかと思っていたのですが、上手くいかず、調べてもイマイチ解らず行き詰まっているのです(内部クラスとはまた別ですよね?)。 もし宜しければ、教えて頂けると助かります。

  • オブジェクトをどう更新するのが良いのか解りません。

    こんばんは、C++でのプログラミングについて質問させて頂きます。 現在DirectXライブラリを使って簡単なゲームを作っているのですが、ゲームのメインループの中で、各オブジェクトをどうやって更新するのが良いのかか解らず、アドバイスをもらえればと思い質問させて頂きました。 現在の更新方法は for(Check_Num=1;Check_Num<PL_Limit;Check_Num++) { PL_Array[Check_Num]->Action();//各オブジェクトを更新 OBJ_Array[Check_Num]->Action(); FIRE_Array[Check_Num]->Action(); } for(;Check_Num<OBJ_Limit;Check_Num++) { OBJ_Array[Check_Num]->Action(); FIRE_Array[Check_Num]->Action(); } for(;Check_Num<FIRE_Limit;Check_Num++) { FIRE_Array[Check_Num]->Action(); } Action関数には、表示を更新する、キー入力で移動する、接触したオブジェクトにダメージを与える、等といった各オブジェクトの動作が書かれています。 最初に定めたオブジェクトを生成できる上限の数まで、片っ端から全て更新していく、といった内容です。 また、オブジェクトの作成は void Player::Shoot_FireBall()//ファイアボール { FireBall* FireBall1 = new FireBall(5,Ref_x(),Ref_y(),charge,"FIREBALL",Ref_angle(),5,0,40,40,4,true,"Action/FireBall1.png",6,3,2,1.0,true,true); if(FIRE_num>=FIRE_Limit) FIRE_num = 1; FIRE_Array[FIRE_num++] = FireBall1; } といった関数を使い、特定のキーが入力された時に呼び出してオブジェクトを作成、上限に到達したら古いオブジェクトが入っていた配列を上書きして作る、といった内容です。 以上のようなソースコードを使ってやっていたのですが、このままオブジェクトの数(弾等の種類や敵の種類)が増えてくると、for文の中にその度に記述を追加していくとあまりにも長くなるような気がするのですが、この方法のままでやっていても大丈夫なのでしょうか・・? 後々効率が悪くなってくるような気がするのですが・・・、どうなのでしょうか、もし今の方法が悪いようでしたら、どう改善すれば良いのかを教えて頂ければと思います、宜しくお願いします。

  • メンバ関数内でオブジェクトを作成する方法について

    こんばんは、C++のプログラミングについて質問させて頂きます。 現在、クラスを作って簡単なゲームプログラムを組んでいるのですが、メンバ関数内でクラスを宣言すると上手くオブジェクトを作成出来ないのです。 例えば、メンバ関数の外、メイン関数内で Player Player1 = Player(320,240,100,50,32,32,3,true,"Character/Character1_A.png"); PL_Array[1]=&Player1; FireBall FireBall1 = FireBall(PL_Array[1]->Ref_x(),PL_Array[1]->Ref_y(),PL_Array[1]->Ref_angle()); ACT_Array[1] = &FireBall1; とすると上手く動くのですが。 このPlayerクラスPlayer1のコンストラクター内で FireBall FireBall1 = FireBall(Ref_x(),Ref_y(),Ref_angle()); ACT_Array[1] = &FireBall1; とすると、FireBall1オブジェクトが生成されないのです。 この状態を改善するためにはどうすればいいのでしょうか、そもそもクラス内で他のクラスを作成する、といった動作自体があまり良く無いことなのでしょうか・・・ お時間がありましたら、お答え頂けると助かります、宜しくお願いします。

  • 画像のラベリング

    画像処理について勉強しています。 画像のラベリングを行うプログラムを書いていたのですが、意図した結果になりません。 以下の関数で実現しようとしましたが、上手くいきませんでした。何か、決定的に間違っている点などがありましたら、教えてください。 また、参考になるWebページなどがありましたら、教えていただけると幸いです。 image2[][]には、レナ画像の512x512を判別分析法を使用して2値化した画像データが格納されています。 また、label[]は全て-1で初期化しました。(initialize()) void labeling(){ int x,y; int up_label,left_label; int label_num=1; //初期ラベル int label_add=1; //ラベルの増分 int max; int i; initialize(); for(y=0; y<y_size1; y++){ for(x=0; x<x_size1; x++){ if(image2[y][x]==0 && label[y][x]==-1){ up_label=left_label=500; if(y-1>=0) up_label=label[y-1][x]; if(x-1>=0) left_label=label[y][x-1]; if(up_label==500 && left_label==500){//(0,0)の地点の処理 label[y][x]=label_num; }else if(up_label==left_label){//上と左が等しい場合の処理 //上と左のラベルが無い場合はラベルを作る if(up_label < 0) label_num += label_add; //ラベルを付与 label[y][x]=label_num; }else{//それ以外の処理 //上と左で小さいほうのラベルを付与する if(up_label<0) label[y][x]=left_label; else if(left_label<0) label[y][x]=up_label; else label[y][x]= (up_label < left_label)? up_label:left_label; } } } } }

  • クラス内で、親ではない他のクラスへアクセスしたい。

    こんばんは、C++のプログラミングに関しての質問です。 現在、勉強がてら作っているゲームプログラミングで、躓いている部分があります。 現在、プレイヤーではないオブジェクトの描画を以下のソースコードで描画しています。 for(Check_OBJ=1;Check_OBJ<OBJ_num;Check_OBJ++) OBJ_Array[Check_OBJ]->Draw_Graph(PL_Array[1]->Ref_x(),PL_Array[1]->Ref_y()); OBJ_ArrayはObjectクラス、PL_ArrayはPlayerクラス、Ref_変数名 は変数名の値を返す関数です。 このソースコードを、Objectクラスのメンバ関数Action()の中に入れたいのですが、エラーが出てしまうのです、ソースコードは以下の通りです。 void Object::Action() { Draw_Graph(PL_Array[1]->Ref_x(),PL_Array[1]->Ref_y()); } エラー内容は error C2227: '->Ref_y' : 左側がクラス、構造体、共用体、ジェネリック型へのポインターではありません。 error C2027: 認識できない型 'Player' が使われています。 です。 Playerクラスが定義されてないと認識しているのかと思い、前方宣言もしてみたのですが改善できず、どうすれば良いのか解りません。 クラス内で他のクラスへアクセスするためには何か他の処理が必要なのでしょうか・・・? 解決方法をご存知の方がいたら教えて頂けると助かります、よろしくお願いします。

  • C言語 DXライブラリ

    #include <math.h> #include "DxLib.h" #define PI 3.1415926f int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); int Handle[3]; LoadDivGraph( "画像/弾01.png", 3, 3, 1, 14, 16, Handle ); float x=320,y=240,angle=0,speed=1; while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){ x += cos( angle ) * speed; DrawRotaGraph( x, y, 1.0, angle+PI/2, Handle[0], TRUE ); } DxLib_End(); return 0; } これを実行すると画像が右に動いていくのですが、なぜ動くのかわかりません。 x += cos( angle ) * speed; の部分はx=320+0*1という事だと思っているのですが、これだとxはずっと320のままで画像が右に動いて行かないと思います。 教えてくださいm(_ _ )m

  • opencvで特定の座標を指定しその座標の色変換

    #include <cv.h> #include <highgui.h> #include <stdio.h> /* グローバル変数 */ CvFont font; IplImage *img; int num1=0; int num2=0; int num3=0; int num4=0; /* プロトタイプ宣言 */ void on_trackbar1 (int val1); void on_trackbar2 (int val2); void on_trackbar3 (int val3); void on_trackbar4 (int val4); int main (int argc, char *argv[]) { img = cvLoadImage ( "bgr.jpg", CV_LOAD_IMAGE_COLOR); cvInitFont (&font, CV_FONT_HERSHEY_DUPLEX, 1.0, 1.0); cvNamedWindow ("Image", CV_WINDOW_AUTOSIZE); cvCreateTrackbar ("X", "Image", 0, 255, on_trackbar1); cvCreateTrackbar ("Y", "Image", 0, 255, on_trackbar2); cvCreateTrackbar ("COLOR", "Image", 0, 255, on_trackbar3); cvCreateTrackbar ("-", "Image", 0, 100, on_trackbar4); cvShowImage ("Image", img); int x,y; uchar p[3]; for (y = 0; y < img->height; y++) { for (x = 0; x < img->width; x++) { p[0] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3]; // B p[1] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3+1]; // G p[2] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3+2]; // R p[0] = num3; p[1] = num3; p[2] = num3; } } cvWaitKey (0); cvDestroyWindow ("Image"); cvReleaseImage (&img); return 0; } /* コールバック関数 */ void on_trackbar1 (int val1) { num1 = val1; char str[64]; printf ( "X=%d Y=%d C=%d -=%d\n", val1, num2, num3, num4); } void on_trackbar2 (int val2) { num2 = val2; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, val2, num3, num4); } void on_trackbar3 (int val3) { num3 = val3; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, num2, val3, num4); } void on_trackbar4 (int val4) { num4 = val4; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, num2, num3, val4); } このプログラムで特定の座標の色変換をしたいのですがうまくいきません。 トラックバー1でX座標 トラックバー2でY座標 トラックバー3で変更後の色 を指定します。 実行すると画像は表示されますがトラックバーを動かしても変化がありません。トラックバーを動かした時にmain関数に戻れば良いと思い、思いつく限り試しましたが上手くいきません。 どなたかアドバイスお願いします。

  • XMLからの画像指定

    PHP初心者です。 現在、API経由で吐き出されるXMLをPHPにて処理しております。 その中で、{photo」の要素である画像「true_image」を、カテゴリー「category」中のコード「code」(ここではCtype→Atype→Btypeの順)を指定して画像を配置したいのです。 以下XML -------------------------------- <item> <photo> <true_image>001.jpg</true_image> <sub_image>001_2.jpg</sub_image> <category> <code>Atype</code> </category> </photo> <photo> <true_image>002.jpg</true_image> <sub_image>002_2.jpg</sub_image> <category> <code>Btype</code> </category> </photo> <photo> <true_image>003.jpg</true_image> <sub_image>003_2.jpg</sub_image> <category> <code>Ctype</code> </category> </photo> </item> -------------------------------- 今のところ、下記のコードで止まってしまっています。。 以下php ---------------------------------- <?php function h($str) { return htmlspecialchars($str, ENT_QUOTES); } $xml = simplexml_load_file("http://api.aaa.aaaa?key=aaaa.aa"); $hits = $xml->item foreach ($hits as $hit) { print<<<EOF <img src="{$hit->photo[0]->true_image}"> <img src="{$hit->photo[1]->true_image}"> <img src="{$hit->photo[2]->true_image}"> EOF; ?> ---------------------------------- xpathを使用して画像を特定する?のでしょうか。 正しいのかどうかも良く分からないで試しているため xpathの指定も何だか良く理解できず、方向性が良く分からなくなってしまいました。 恐らく初歩の初歩なのでしょうが、迷路に入ってしまったようです。 道先の案内でもして頂けると助かります。。

    • 締切済み
    • PHP
  • 直線と点の距離を使って当たり判定を作りたいのですが

    こんばんは、C++のゲームプログラミングで、当たり判定を作成しているのですが、どうしても上手くいかず、困っています。 エラー等ではなく、単純にどこが間違っているのか解らない、といった類の質問をするのはあまり良く無いのかもしれませんが、自分ではどうすればいいのか解らないので、ここで質問させて頂きます、よろしくお願いします。 作りたいのは、あるオブジェクトCの頂点の座標から直線の方程式、ax+by+cの、a,b,cを求め、接触しているからを確認したいオブジェクトTの頂点座標との距離を |ax0+by0+c|/√a*a+b*b の式を使って求めるプログラムです。 ソースコードは以下になります。 bool Object::Check_Collision2(Object Collision) { Sub_bShow(false);//自分自身には処理をしない。 point C[5]={0};//対象の頂点4つ、計算しやすいように配列は5つまで作ってある。 point T[4]={0};///呼び出し側のオブジェクトの頂点4つ double C_Distance = sqrtf((Collision.Ref_x_size()/2*Collision.Ref_x_size()/2)+(Collision.Ref_y_size()/2*Collision.Ref_y_size()/2));//中心から頂点までの距離を計算 double T_Distance = sqrtf((Ref_x_size()/2*Ref_x_size()/2)+(Ref_y_size()/2*Ref_y_size()/2)); for(int i=0;i<=3;i++) { //頂点の値を配列に代入 C[i].x = Collision.Ref_x() + cos((Ref_Angle()+45+(90*i)) * PI / 180.0f) *C_Distance; C[i].y = Collision.Ref_y() + sin((Ref_Angle()+45+(90*i)) * PI / 180.0f) *C_Distance; T[i].x = Ref_x() + cos((Ref_Angle()+45+(90*i)) * PI / 180.0f) *T_Distance; T[i].y = Ref_y() + sin((Ref_Angle()+45+(90*i)) * PI / 180.0f) *T_Distance; } C[4].x=C[0].x; C[4].y=C[0].y;//forで計算しやすいようにするための処理 //あとは二点間の直線の方程式 ax+by+cを求めて、点と直線の距離の公式で出来る・・・はず。 if(Collision.Ref_bShow()==true)//確認する対象は参照するべき相手かを確認 { if(Collision.Ref_Collision()==true)//当たり判定を有するか { for(int i=0;i<=3;i++) { for(int j=0;j<=3;j++) { double a =(C[i].y-C[i+1].y); double b =-(C[i].x-C[i+1].x); double c =( ((C[i].x-C[i+1].x)*C[i+1].y) - ((C[i].y-C[i+1].y)*C[i+1].x)); //呼び出したオブジェクトと引数のオブジェクトの接触を判定する if ( (fabs((a*T[j].x)+(b*T[j].y)+c) /hypot(a,b))<=10.0 ) { return(true); } } } return(false); } else { return(false); } } else { return(false); } } このソースコードで試してみたのですが、上手くいかず、数値を確認してみると、(fabs((a*T[j].x)+(b*T[j].y)+c) /hypot(a,b))の値がTの座標が違うところでこの関数を呼び出しても値が同じだったりと、おかしな結果になってしまいます(どうおかしい結果なのかも書くべきなのだとは思うのですが、法則性をまだ見つけられていないので・・・) もしどの部分が間違っているのかが解りそうでしたら、教えて頂けると助かります、数学的知識の勘違いや、単純なくだらないミスなのかもしれませんが、宜しくお願いします。

  • 画像処理のプログラムについて

    初めまして、こんにちは C言語で画像処理のプログラミングについてご解答をお願いします 現在二値化した白黒バーコードに対して、ビット数埋め込みというものを行っています この画像に埋め込んだビットを、検出するプログラムを作成したいのですがどうしたらいいでしょうか? ソースコードは以下です int x,y,i,j; double Th = 128.0; /*2値化の際のしきい値 */ int x_StartPos, y_StartPos,x_EndPos,y_EndPos; /*バーコードが描画されている領域の座標 */ int num; y=0; while (y<biHeight){ x=0; while(x<biWidth){ if (Y[y][x]<Th) break; x++; } if (x < biWidth){ x_StartPos = x; y_StartPos = y; break; } y++; } if ((x_StartPos==0) && (y_StartPos==0)) { printf("画像中に黒領域が見つかりませんでした"); exit(-1); } x_EndPos=0; while (x<biWidth){ /*画面右までスキャンして、一番右端の黒のx座標を求める*/ if (Y[y][x] < Th)/* 黒い点であったら */ x_EndPos=x; x++; } if (x_EndPos==0) { printf(" バーコード右端が検出できませんでした\n"); exit(-1); } /*バーコード一番上のラインにおける、黒の画素の数を数える*/ x=y_StartPos; y=y_StartPos; num=0; //これまでに検出した黒画素の数 while(x<=x_EndPos){ if (Y[y][x] < Th) // 黒い点であったら num++; //黒画素数を +1 する x++; } *start_x= x_StartPos; *start_y= y_StartPos; *end_x = x_EndPos; *num_of_blackpixels =num; } void Embed_watermark(double Y[Y_SIZE][X_SIZE],double Y_out[Y_SIZE][X_SIZE], int sukasi[], int Length, int x_StartPos, int y_StartPos, int x_EndPos) { int x,y; int bitnum; double Th = 128.0; /*2値化の際のしきい値 */ for(y=0;y<biHeight;y++) //出力データに元データをコピー for(x=0;x<biWidth;x++) Y_out[y][x]=Y[y][x]; bitnum=0; //現在何番目のbitが埋め込み対象になっているのか x=x_StartPos; y=y_StartPos; //埋め込み開始 while(x<=x_EndPos){ if (Y_out[y][x]<Th){ //もし注目点が黒画素なら透かし埋め込み処理を行う printf("found! x=%d bitnum=%d\n",x,bitnum); if (sukasi[bitnum]==0){ // 「0」を埋め込むなら、該当画素を白くする Y_out[y][x]=255; } bitnum++; //埋め込み対象を次のビットにする } if (bitnum==Length) // もし全てのビットの埋め込み処理が終了したら break; x++; } printf("埋め込みが完了しました.埋め込み終了x座標=%d\n",x); } void main(void) { int Length = 20; // 埋め込む透かしのビット長 int suuchi[]={1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,0,0,1,0}; //埋め込む透かしビット char *input="bar.bmp"; char *output="out.bmp"; /* 画像中のバーコードが書かれている左上端の座標 */ int x_StartPos; int y_StartPos; int x_EndPos;//バーコードx座標の終端 int Num_of_Blacks; //バーコードの横方向の黒画素数(=埋め込めるビット数の上限)

専門家に質問してみよう