アプリ版:「スタンプのみでお礼する」機能のリリースについて

プログラムに悩んでいるものです.

とある画像処理のプログラムを組んでいるのですが,処理が遅くテーブル引きを組んでいます.
三角関数などはすんなりできたのですが,質題にもある通りsqrt(a^2+b^2)が実現できず,この場を借りて質問させていただきました.
以下にプログラムの一部を示します.
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
void filter(unsigned char* d, short *dx, short *dy, int w, int h)
{
///// テーブル生成 /////
static int c_size = 0;// static 次の呼び出しでも値保持
static double *c_sqrt = NULL;//
c_size = 255;              // u,v:0~255
c_sqrt = (double *)malloc(sizeof(double)*c_size*c_size);// 領域確保
for(int i=0; i<c_size; ++i){    // 有りえるすべての値を生成
for(int j=0; j<c_size; ++i){
c_sqrt[i*j] = sqrt( (double)(i*i + j*j) );
}
}
///// d = sqrt(dx^2 + dy^2) /////
for(int y = 1; y < h-1; ++y){
for(int x = 1; x < w-1; ++x){
double u = (double)dx[y*w+x];
double v = (double)dy[y*w+x];
int val = (int)c_sqrt[ (int)(u*v) ] /4;
if (val>255) val=255;
d[y*w+x] = val;
}
}

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
見てご察し頂ける(?)と思いますが,この関数は何回も呼び出すので,上のほうででテーブル引きしようとしてます.
ただ明らかなプログラム経験不足のためかうまくいってません.
個人的にはc_sqrtを別途関数c_sqrt(u,v)にしたほうがよいのかと思ってます.
どういうプログラム記述をすれば,このテーブル引きが実現できるでしょうか?
ご回答,お力添え,よろしくお願い致します.

A 回答 (5件)

何をやりたいのか今ひとつ見えませんが、


c_sqrt[i*j] = sqrt( (double)(i*i + j*j) );
とやってしまうと、
i=2、j=8の時には
c_sqrt[16]=√(2*2+8*8)=√68

i=4、j=4の時は
c_sqrt[16]=√(4*4+4*4)=√32
ということで、c_sqrt[16]が上書きされてしまいますが、それで良いんでしょうか?

sqrt(a^2+b^2)
の値引きテーブルを作るならc_sqrt[a][b]のような二次元配列で用意してやるのが常道ではないかと思います。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます.
何をやりたいのかわからなくてすいませんでした.説明不足だったと思うし,プログラム構成がダメダメだったと思います.
ご指摘の通り,二次元配列をつかったら動作しました.
これ関連の質問をしているので,お力添え頂けると幸いです.
質問URL:http://okwave.jp/qa/q7112041.html

お礼日時:2011/11/04 01:42

1. static double c_sqrt[c_size][c_size];をグローバルに用意する。


static *double にして動的に確保しても良い。が、めんどい。
まずは静的に作れるようにしてから改造してはどうか。

2. 配列テーブルを作る。
void make_csqrt(){
int i,j;
for(i = 0; i < c_size; i++)
for(j = 0; j < c_size; j++) c_sqrt[i][j] = sqrt((double)(i*i) + (j*j));
}

3. 呼び出す。
double mysqrt(int a,int b){return c_sqrt[i][j];}

備考:
もしも、使用する値に特定の偏りがあるようだったら、「ハッシュ法」を使用すればよい。
サンプルは山ほど落ちている。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます.
ハッシュ法などは知らなかったので,勉強になりました.
この質問関係の質問をしているので,お力添え頂けると幸いです.
質問URL:http://okwave.jp/qa/q7112041.html

お礼日時:2011/11/04 01:37

2次元配列を使わないなら


宣言 c_sqrt[ROW][COL]
使用 c_sqrt[row][col]
なら
→c_sqrt[row * COL + col]
という感じです。
同様なことは
> d[y*w+x] = val;
で使用してますよね。

このプログラムなら COL = c_sizeなので
c_sqrt[i*c_size + j] = sqrt( (double)(i*i + j*j) );

あと、これ、何回も呼び出すとありますが、そのたびにc_sqrtを確保→計算するようになってます。これではテーブル引きにした意味がありません
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます.
ご指摘の通り,テーブル引きの意味がない状態だったので,助かりました.
これ関連の質問をしているので,お力添え頂けると幸いです.
質問URL:http://okwave.jp/qa/q7112041.html

お礼日時:2011/11/04 01:38

>個人的にはc_sqrtを別途関数c_sqrt(u,v)にしたほうがよいのかと思ってます.



関数名は置いとくとして、ご自分でも思ってらっしゃる通り別途関数にした方がよいかと思います。
テーブルは一次元配列でやろうとするより、素直に二次元配列の方がわかりやすいのではないでしょうか。

>c_sqrt[i*j] = sqrt( (double)(i*i + j*j) );

それもあって、c_sqrtの添え字が i*j とおかしな事されてるようですし。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます.
ご指摘の通り,二次元配列じゃないとおかしな状態だったので,助かりました.
これ関連の質問をしているので,お力添え頂けると幸いです.
質問URL:http://okwave.jp/qa/q7112041.html

お礼日時:2011/11/04 01:39

>c_sqrt[i*j] = sqrt( (double)(i*i + j*j) );



c_sqrt[i*j]
としているのがまずいと思います。
【理由】
例として、i が 0 の場合を考えてみます。このとき、j がどの値であっても i*j は 0 です。
その結果、せっかく j を 0 から 254 までループさせても、c_sqrt[0] を255回書き換えるだけです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます.
ご指摘の通り,c_sqrtがまずかったです.
これ関連の質問をしているので,お力添え頂けると幸いです.
質問URL:http://okwave.jp/qa/q7112041.html

お礼日時:2011/11/04 01:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!