方法 - みる会図書館


検索対象: 月刊 C MAGAZINE 2001年4月号
61件見つかりました。

1. 月刊 C MAGAZINE 2001年4月号

00 フログラミング入門 w0 = List 4 曾 1 = 響 1. WHERE 注文日 D. 得意先 = ”十 PrmKyakuI*tsuGetsujiSelKyaku—>Text 十 WHERE 注文 . 得意先 = ”十 FrmKyakubetsuGetsujiSelKyaku->Text 十” WHERE 注文日 D. 年月 > = ' 第十十を 00 : 00 ' WHERE 注文 . 年月 > = ' + ” AND 注文 . 年月く = 十十物 00 : 00 ” ”十 FrmKyakubetsuGetsujiDateEnd->Text 十 23 : 59 ” 十” AND 注文ーの . 年月く = ”十 FrmKyakubetsuGetsujiDateEnd->Text 十 23 : 59 ” w0 = w0 + 第注文冊 . 年月 = 響 1 十注文冊 . 年月 十″み D 注文ー D. 年月く = ”十十” 23 : 59 ” ″十十物 00 : 00 ' 新 十” AND 注文 . 年月く = ”十 FrmKyakubetsuGetsujiDateEnd->Text 十物 23 : 59 ” 》 = 冖十十” 00 : 00 ” vsql + = ” AND 注文数量◇ 0 ”・ Vsq ー十 = w1 ー sql + = ″ OUP BY 得意先″・ gq ー十 = WO; FrmKyakubetsuGetsujiReportRepoter—>Preview ( リ App ー ication—>ProcessMessages ( while (rrmKyakubetsuGetsujiReportRepoter->AvailabIe = = false) = true; FrmKyakubetsuGetsuj iMasterDataSet—>Active = true ー FrmKyakubetsuGetsuj iMasterDataSet—>CommandText = sq 嵭 FrmKyakubetsuGetsujiSIaveDataSet->Active = false; FrmKyakubetsuGetsuj = fa ー se ー FrmKyakubetsuGetsujiComand->Execute ( FrmKyakubetsuGetsujiCommand->CommandText = vsql; vs 印 + = ” OUP BY 注文 . 得意先 , 注文 D. 商品 , 注文 D. 単価” 継続に制限がある ) 済みます。 クエリビルダで作成した文字列をそのま まソースに貼り付けて " で囲めば OK です。 List 4 はサンプルアプリケーションのユニ ットソースの抜粋です。 VB を見慣れている 人にも C + + に慣れている人にも奇妙に見え るでしよう。 SQL 文を作成している部分は VB 的に文字列を ' + ' でバシバシ結合してい ます。メソッド呼び出しやプロバティの設 定は C 的に [ オプジェクト ] - > [ メソッド名 or プロバティ ] となっています。フォームク ラス名が Frm ? ? ? と VB 的な命名になって いるため C + + BuiIder な人は「何じやコリャ ? 」 という感じでしよう。 プログラム全体を説明するには誌面がぜ んぜん足りないので , プロジェクトを実行 できるまでの手順を説明します。 ①データベースを作成する mknewdb. ⅸ t をデータベース付属のクエ リツールで実行します。このテキストは Mic roso れ SQL Server 6.5 , 7.0 , MSDEI. 0 での 動作を確認していますが , そのほかのデー タベースエンジンでも少し手直しすればテ ータベースを作成できる程度の基本的な SQ L しか使っていません。 また , 使用するデータベースエンジンは , ADO プロバイダでサポートされている必要 があります。 ② ADO 接続文字列を構築し , ソースに埋め込む C + + Builder を起動し , サンプルプロジェ クトを開きます。 [ 表示 ] → [ フォーム ] メニ ューで FrmMaster フォームを表示し , オプ ジェクトインスペクタで FrmMasterDataSet を選びます。 ConnectionString を①で作成したデータ べースに接続できるように設定します。そ の文字列をクリップボードに削除コピー ( 切 り抜き ) します。次に Main. h を開いて R CONNECTION マクロにクリップポードか らコピーした文字列を設定します。 かゆ VB よりもずっと簡単に記述できる点で , C + 高度発展言語なので , 非常に泥臭い部分も という点で , そして何といっても C + + は C の 私は VB よりは「痒いところに手が届く」 は難しいことではありません。 ータベースアプリケーションを作成するの 度コツをつかんでしまえば C + + Builder でデ には使うのは難しいものです。ですが ていますが , おおよそデータベース初心者 管理者向けのツールがひととおり用意され データベースエンジンにはたいてい開発者 , だけでもそこそこの技術力が要求されます。 ースアプリケーションは動かす環境を作る 実のところ , 現在の Windows でデータベ 実行ファイルを生成する ③コンバイルして 最後に + BuiIder を高く評価しています。 ださい。 れ以外の用途には , 改変・流用はご遠慮く 用に限って自由に改変 , 配布できます。そ コンパイルされた結果は , 個人の学習的利 なお , サンプルの全ソースコードおよび していただけたら幸いです。 データベースへのクエリ方法などを参考に ひょりよいアプリケーションの作成のため ースに接続できる環境が整備できたら , ぜ 送確認部分が作られていません。データベ 実績を客別 , 商品別に印刷するだけで , 配 サンプルアプリケーションは伝票を入力 , す。 く浅くになってしまった点を反省していま 実践的な話をしようとしたため , 内容が広 ったのですが , 限られた誌面でできるだけ 部分にまでもっと踏み込んで書ければよか もっと実際的なアプリケーションの作成 66 C MAGAZINE 2 側 1 4

2. 月刊 C MAGAZINE 2001年4月号

00 フログラミング入門 今回はこれはまずい仕様です。価格改定前 プルを持ったデータベースが作成されます。 だと思われます。では , データベースアプ このようなスクリプトは直接プログラムに に売れたピザの単価まで変更になってしま ーマンスを左右する リケーションのパフォ い , 実際の金額と合わなくなります。 埋め込むこともできますが , 普通はインス 要因は何でしようか ? 正規化は実際の運用を十分に考慮して行 トール時点に 1 回だけ実行すれば済むので , インデックスとクエリ 私はプログラムから独立して管理する方法 います。 List3 は , 今回利用するテープルを持つ を採用しています。 データベースアプリケーションのノヾフォ データベースを作成する SQL スクリプトで さて , 冒頭では「作成するアプリケーシ ーマンスの大半は , クエリをデータベース ョンのターゲットは最低でも 1 万件のデー 工ンジンが実行する速度で決まります。 す。一般的に ACCESS のようなツールはデ タを扱うアプリケーション」と大風呂敷を ータベースを「利用」するのには向いていま のピザ屋さんのアプリケーションでも 1 年 , 2 年と営業を続けるとしだいに処理が遅く すが , 今回のようなアプリケーションを「設 広げました。実は , データベースアプリケ 計 , 作成」するのには向いていません。テ ーションにおいてはプログラム上でのコー なってきます。とくに「注文 HD 」と「注文 D 」 ディングテクニックは , ほとんどパフォー ープルデザイナもトライ & 工ラーで作るの はどんどん肥大化するテープルなので , には便利ですが , やはり「設計」には向いて マンスには貢献しません。この点が VB と比 の 2 テープルに対するクエリは十分に注意 いません。 List2 のスクリプトは SQLServer べると , C + + でデータベースアプリケーシ して設計する必要があります。この 2 テー の ISQL ツールで実行すればいくつかのテー ョンが作成されることが少ない要因の 1 つ プルは , テープルのキーフィールド以外に [ 年月 ] と [ 得意先 ] で検索されます。また , List 3 [ 商品 ] も検索の対象となりえるでしよう。 一般的に Fig. 3 のようなリレーションを持 つフィールドは検索の対象となります。 検索の対象となるフィールドにインデッ クスを作成することは , 効果的なパフォー マンス対策の 1 つです。ですが , やみくも にインデックスを作成しても意味のない , 逆に害になる場合もあります。今回の例で は「注文 D 」の [ 商品 ] フィールドがその例だ と思われます。なぜなら , 商品がインデッ クスを作成しなければ検索に時間がかかる ほど「広がった」テープルではないからです。 せいぜい 100 種類程度しか商品が分散しな い場合はインデックスは役に立たないので , データベースエンジンはインデックスを利 用しません。インデックスの作成は検索す るのに効果的ですが , 新規のレコードを追 加する場合にはその計算時間がオーバヘッ ドになります。 もう 1 つ重要な点は , データをどのよう なデータタイプでデータベース上に所持す るかという点です。今回の例では「商品」の [ コード ] フィールドです。商品を数値で分 類するという理念でデータベースを設計す れば [ コード ] フィールドを数値で持つのは 妥当な結論です。ですが , 桁のある範囲が 意味を持つような分類を行う JAN コード , / * 注文伝票 * / --drop table 注文 create セ曲注文 ( 土 n し ID 年月 datetime 得意先 char(6) ID 風 lffh 1 , 1 ) NOT NULL PRIMARY KEY CLUSTERED, DEFAULT getdate( ) NOT 肌ル L , DEFAULT 0000 NOT NULL, create d 注文ー得意先 on 注文冊 ( 得意先 ) go c て田セ e index 注文一年月 on 注文 ( 年月 ) go / * 注文伝票明細 * / --drop table 注文 D create セ曲注文 D ( int DEFAULT 0 ID NOT NULL, IDENTITY(I,I) NOT 肌ル L 年月 DEFAULT getdate( ) datetime NOT NULL, DEFAULT ' 0000 ' ch ( 4 ) NO で NULL, 注文数量 float DEFAULT 0 NOT NULL, 配送確認 char(l) NO NULL DEFAULT 単価 DEFAULT 0 NO で NULL, money CONSTRAINT 注文 D—KEY PRIMARY KEY CLUSTERED (ID, ID—D) create index 注文 D 一年月 on 注文 D ( 年月 ) go CREATE VIEW V 注文 D AS SELECT 注文 D. ID, 注文 D. 年月 , 注文 D. 商品 , 商品 . 商品名称 , 注文 D. 注文数量 駅 OM 注文 D I JOIN 商品 ON 注文 D. 商品 = 商品 . コード 64 C MAGAZINE 2 1 4

3. 月刊 C MAGAZINE 2001年4月号

00 フログラミング入門 たとき ( 皆無ではない ) , なかなか「このコ ンパイラはおかしい」とまでは言いにくい ものですが , 規格書を持っていれば断言す ることができるのです。 解説書・入門書 プログラミング関係の本の中では , 解説 書・入門書が過半数を占めるのではないで しようか。これも 1 つは持っておきたいです ね。入門書だからといって , 学習時に使う だけではありません。規格書ほどの正確さ は必要なく , ちょっとしたことを調べたい ときなど , 便利なものです。 本屋に行くと , 「 C 入門」とか「 Java 入門」 とか , あるいはそれに類した本がいつばい あります。ありすぎて , いざ買うとなると 迷うかもしれません。どれを選んだらいい かというと , 無責任なようですが , 自分が 気に入ったものを選びなさいとしか言えま せん。評判のいい本悪い本はたしかにある のですが , それよりも大事なのは読む人と の相性だと思うからです。たとえば筆者は , プログラムの実例が多い入門書よりも , 文 法や規約などが細かく書いてあるほうが好 きです。だけど逆の好みの人も多いと思い ます。また , 硬い文章だと退屈で読みにく いと言う人がいる一方 , 逆に軟らかい文章 だとなんだか落ち着かないという人もいる でしよう。買う前に立ち読みして , 自分の 好みに合ったものを見つけてください。 しかし付け加えるとすれば , 索引が立派 な本のほうがあとあと便利だと思います。 調べものをするときには , 詳細な索引があ るのと , 索引がなかったり貧弱だったりと いうのとでは使いやすさがかなり違います。 ノウハウ本 余裕があれば買っておきたいのがノウハ ウ本です。 C , C + + , Java, Small ね lk などの 新で「文法はだいたい覚えた」というレ に 1 ローコ , ベルの人向けに , ノウハウ ( コツ , 秘訣 ) を 教えてくれる本があります。いくつか例を あげておきましよう (Fig. 4 ) 。 22 C MAGAZINE 2001 4 アルゴリズム本 先に , 言語とは独立に「アルゴリズム」と いう分野があると言いました。アルゴリズ ム関係の本も , そろえておくべきです。知 識の価値としては , 言語よりアルゴリズム の知識のほうが高いくらいです。 基本的なアルゴリズムには , 整列 , 探索 , 文字列探索 , 構文解析 , 乱数・・・・・・などがあ ります。またそれを実現するためのデータ 構造として , リスト , スタック , キュー B 木とかいろいろあります。意識して勉強 するようにしてください。 ところで , アルゴリズムについての情報 収集はちょっと難しい面があります。整列 とか探索とか , 基礎的なアルゴリズムにつ いての資料は割とあります。しかし , 見つ けづらい資料は , 探してもなかなかないの です。 これは , アルゴリズムとーロにいっても 分野が広すぎて探しにくいのが原因です。 ものによっては , 特許が絡んでくることが あります。そのほかにもいろいろあって , 特殊なアルゴリズムを調べるということは かなり難しい作業です。残念ながら , 筆者 もまだこれといった方法をつかんでいませ ん。事例ごとに地道に探すしかないのかも しれません。 アルゴリズムに限らず , ちょっと特殊な ことを調べようと思うと難しいものです。 そういう場合 , 最後の手段として人に聞く か , それもできないときはあきらめてしま Fig. 4 ノウハウ本の例 情報の根を張る うのも手かもしれません。 あきらめる前に , 情報の根を張る探し方 を試してみましよう。 ある問題を抱えているとします。最初に 図書館で一一 - 実際には書店で行うことが多 いのですが一一一背表紙をひととおり見て , もっともその問題に近そうな本を手にとり ます。問題が特殊だと , 1 冊見た程度では 答は見つかりません。しかし , 本にはたい てい「参考文献」なるものが書いてあります。 次のステップとしてその参考文献をできる 限り見てみます。それでも見つからなかっ たら , 参考文献に書いてある参考文献 , そ のまた参考文献・・・・・・と見ていきます。 ものすごく効率が悪いと思うかもしれま せんが , それほどのことはありません。本 を全部読む必要はありません。目次と索引 さえ見れば , 探している答が載っているか どうかはわかるものです。 W Ⅵで探すときにも原理は同じで , 関 係ありそうなサイト , そこからのリンク , さらにリンク・・ ・・と広げていきます (Fig. 5 ) 。そうやってたどっていると , 「どうもこ の方向は関係なさそうだ」とか「解に近づい てきたようだ」ということはなんとなくわ かります。関係なさそうな気がしたら戻り , 近いような気がしたらそこらへんを重点的 に探します。人工知能の分野ではこういう やり方を「ヒューリスティック探索法」とい うそうです。 何段回か繰り返すと , 多くの場合 , 答が 見つかります。もっとも , これでも見つか らないことがあります。そういうときは一 般人が手に入れるのは難しい情報であるか もしれません。しかし少なくとも答を「手 Smalltalk Java ℃プログラミング専門課程」 , 藤原博文 , 技術評論社 TEffective C + + 」 , Scott Meyers , 吉川邦夫訳 , アスキー 「 Java の格言」 , ウォーレン / ビショップ , 安藤慶ー訳 , ピアソン・エテュケーション 「 Java パフォーマンス戦略』 , ラーマン / ガスリー , 安藤慶ー訳 , ピアソン・エデュケーション 「 Sma Ⅱ talk イディオム」 , 青木淳 , ソフト・リサーチ・センター

4. 月刊 C MAGAZINE 2001年4月号

ントに比べ , 塗りつぶしを行うか否かの条 ョンが考えられますが , 簡単なものとして メータや条件式を加えたり , まったく別の 件にバリエーションが付けやすいため , 任 式を使用しなければならないこともありま は , 意の条件を満たす領域を抽出したいケース lv-vs I< す。領域抽出においては , この判別式をい には適用範囲が広くなります。ただし , 画 IV-Vn I< かに設定するかが , リージョングローイン 素の探索やバッフアなどにおいて , シード という式がよく使われます。 グを利用するうえでのポイントになるとい こで , V が ペイントよりも効率が悪い面があります。 判別を行う対象の画素値 , Vs は始点の画 えます。 実際の画像にリージョングローイングを 素値 , vn は隣接する画素値です。この 2 式 適用して , ROI を抽出する場合 , ほとんど を同時に満たすとき , その画素を領域内と 近傍について のケースで ROI の性質に合わせて処理方法 みなします。 を考える必要があります。今回はリージョ ①式はコンスタントな値との比較なの リージョングローイングでは , 領域内の ングローイングの基本的な考え方を理解す で , 画素値がある範囲に入っているかどう 探索において , 対象画素の近傍の画素を調 ることを目的に , 比較的単純な処理を例と かを判別することができます。これに対し べていきます。近傍については , 以前の二 して説明します。 て②式は , 隣り合う画素値との差 , つまり 値画像処理を取り上げたときに説明しまし 局所的な色の変化が激しいか否かを判断す たが ( 2000 年 8 月号 ) , 簡単におさらいして リージョングローイング る条件式です。局所的な色の変化とは , す おきます。 なわち工ッジを指します。ですから②式は 「近傍の画素」とは , 文字どおり隣り合 リージョングローイングは , 画像内の 1 領域境界における工ッジの情報を判別する う画素のことですが , 「隣り合う」という 点から始めて , その近傍の画素のうち , 領 式となります。領域境界部においては工ッ ことをどのように定義するかによって , 2 域内とみなせる画素をつぎつぎに取り込み ジが強くなる傾向があるので , これを利用 次元画像においては , 2 種類の近傍が存在 ながら , 領域の抽出を行うものです。 Fig. しています。 します。画素の辺を共有する場合のみ , 隣 1 にリージョングローイングの処理イメー なお , パラメータ住をグローバルバラメ り合う , というように定義すると , Fig. 2 - ジを示します。リージョングローイングの ータ , 滝をローカルバラメータと呼ぶこと (a) にあげるような画素が近傍となります。 処理の流れは , 次のようになります。 もあります。このローカルバラメータを持 一方 , 辺だけでなく , 頂点を共有している 1 ) 始点の 1 点をバッフアに記録 てるところがシードベイントとの違いの 1 場合も近傍とみなすように定義すると , Fi 2 ) バッフア内の点を取り出す。なけれ っといえます。ローカルバラメータを持つ Fig. 2 近傍 ば処理終了 ことにより , 「同じ色の範囲を塗る」「同じ 3 ) 取り出した点の近傍を調べ , 条件を 色の範囲にある部分を塗る」といった単純 満たす場合は , 塗りつぶしを行う。ま 処理だけでなく , 工ッジ的な要素を考慮し た , 同時に新しく塗りつぶされた座 た塗りつぶし処理が可能になります。 標をバッフアに追加する ただ , 先の式ではパラメータが 2 つあり , 4 ) 2 ) から繰り返し それぞれについて最適なパラメータの組み こで , バッフアは , 3 ) で取り出しを 合わせを求めるのが難しいという問題もあ ります。単純な領域に対して塗りつぶしを 行うまでデータを保持できるエリアです。 行いたい場合は , ローカルバラメータを使 プログラムとして実装する場合には前回説 明した FIFO'S ッファ , LIFO バッファいず 用するとかえって不便になるので , このよ れかを用いればよいでしよう。ここては うな場合はグローバルバラメータのみを使 FIFO バッフアを利用することにします。 ってもまったく問題はありません ( Photosh 塗りつぶしを行うか否かを判別する条件 op などのツールで提供されている , マジ 式は , さまざまなものが考えられます。場 ックハンドによる領域指定はグローノヾルバ 合によっては , 処理中の領域の形状や位置 ラメータのみのリージョングローイングだ などの情報を用いて判別することも考えら と思われます ) 。 れますが , こではもっとも簡単な例とし しかし , 画像から任意の領域抽出を行い て , 画素値のみを判別の材料にします。画 たい場合には , 先ほどの 2 式だけでは不十 素値のみの場合でもさまざまなバリエーシ 分なケースがほとんどで , これ以外のパラ (b) 8 近傍 (a) 4 近傍 0 ■ 00 一 0 ■■ 0 Fig. 3 採用する近傍によって結果に差が生じるケース ※ 4 近傍を採用した場合は , A の部分のみ が塗りつぶされるが , 8 近傍を採用する と B の領域まで塗りつぶされてしまう 100 C MAGAZINE 2001 4

5. 月刊 C MAGAZINE 2001年4月号

五ロ 一三ロ です。 偽の値については今後よく出てくるのでし ・整数値で除算を行うと小数点以下は切 っかり覚えておきましよう。 り捨てられる 条件判断には if 文を使用します。処理を ・整数に対して % 演算子を使用すると , 行うときに「もし ~ なら」という条件を与え 余りを求めることができる る場合に使用します。 迂 ( 条件 ) { 条件に合った場合の処理 } ・ 0 で除算を行うことはできない。工ラ ーになるので変数の値に注意が必要 と記述します。 List7 は関係演算子と条件 ・計算は左側から順に計算される 文の使用例です。 ・優先順位は数学と同じ。「 * , / 」は 論理演算子 「 + , - 」より優先され , 「 ( ) 」 ( カッコ ) があるとその中がさらに優先される ・計算処理時には基本的には整数同士 , 論理演算子は真偽値を否定したり , 先ほ 次に , プログラミングには必ず必要な演 実数同士で行うが , 混合させて計算す ど説明した条件を複数組み合わせたりする 算子の基本事項を説明します。はじめに覚 ることもできる。その場合 , その答え 演算子です。論理演算子の一覧を TabIe 11 えなければいけない演算子は以下の 3 つです。 は実数表現になることがある に示します。 ・算術演算子・・・数値の計算を行う List 6 は算術演算子の使用例で , Fig. 6 が Table 11 の演算子 ! ( 否定 ) の例で , ・関係演算子・・・ 2 つの数値 ( cha 「型は文字 実行結果です。 Fig. 6 List 6 の実行結果 コード i 猷型として認識される ) の 関係演算子 大小関係を判定する ・論理演算子・・・真偽値を否定したり , 複 数の条件を組み合わせたりする 関係演算子は , 2 つの数値 (char 型は文字 コード int 型として認識される ) の大小関係 算術演算子 を判定し , 真 ( 与えられた条件を満たす場 合 ) なら 1 , 偽 ( 与えられた条件を満たさな い場合 ) なら 0 を返す演算子です。関係演算 算術演算子の一覧を TabIe 9 に示します。 子の一覧を TabIe 10 に示します。この真と 以下は算術演算子を利用するときの注意点 TabIe 10 関係演算子 演算子 より小さい より大きい より小さいか等しい より大きいか等しい 等しい 等しくない TabIe 11 論理演算子 説 明 演算子 ・ c = 0X41 ; ・・・ 16 進数コード 文字コードをすべて覚える必要はありませ んが , これらの表現方法とその違いは覚え ておきましよう。 また , このほかに先ほど登場したエスケ ープ文字列を含む , 表示用の文字コードで はなくそれぞれの意味や機能を持つ文字コ ードもありますが , ここでは省略します。 演算子 整数 積 = 33 整数 商 = 3 整数 余り = 2 整数 和 = 14 整数 差 = 8 実数 商 = 3.666666 List 演算子を使ったプログラム 、 1 : #include く 8 セ dio. h> 4 int ia, ib, , id, ie, ih, 土新 float fa, fb, fc; 土 a = 1 土 b = ic=a*b ー 9 : id=a/b; ユ 0 : 土 e = a 宅 ユ 1 : 土 h = a 十 12 : 13 ま p て土れ tf ( ”整数 積 = 宅 d % 土 0 ユ 4 : p て i れ tf ( ″整数 商 = 貊 % 土 d 15 : て intf ( ”整数 余り = 記”は e ユ 6 p て土 ntf げ整数 和 = 宅 d % 土 h 17 ま p て土 ntf ( ”整数 差 = 宿 d ” , 土土 18 19 : 20 : fa=ll. 21 : 。 fb = 3. fc=fa/ fb; 22 ま pr 土北 f ( ”実数 商 = 社 % fc 23 : 補足 例 説明 a<b a>b a く =b a>=b 等値演算子 否定演算子 例の意味 a が真 ( 0 以外 ) でなければ ~ a が 0 より小さくなければ ( a = = 0 または a > 0 ならば ) 0 く a かっ a く 100 ならば ~ a = = 10 または a = = 100 ならば ~ 例 if(!a) 否定 論理積 ( ~ かっ ~ ) 論理和 ( ~ または ~ ) if(!(a く 0)) if(0<a & & a く 1 00) if ( a = = 10 Ⅱ a = = 100 ) 39 特集 プログラミング入門 C 言語入門講座

6. 月刊 C MAGAZINE 2001年4月号

00 フログラミング入門 は , ディレクトリの区切りを表します。先 頭にある \ 記号は , ルートディレクトリを 表しています。また , Fig. 2 と同様の構成 をした C ドライプがあった場合は , C : %APP*F I LE*DOC*XYZ . EXE と表します。先頭の C : が C ドライプを表し ます。このように表現したファイル名を , フルバスファイル名 , ディレクトリまで ( フ ァイル名を指定しない ) を表現した場合は フルバス名と呼びます。 カレント PC には複数のドライプが存在できます。 ところが MS-DOS/Windows が一度に同時 に扱えるドライプは 1 つです。ドライプには 複数のディレクトリが存在できますが , MS -DOS/Windows が一度に同時に扱えるディ レクトリは 1 つです。工クスプローラでさま ざまなドライプのさまざまなディレクトリ をたくさん開けるのでそのようには感じな いかもしれませんが , 1 つのドライプの 1 つ のディレクトリだけを注目しているのです。 現在注目しているドライプをカレントドラ イプ , 現在注目しているディレクトリをカ レントディレクトリと呼びます。 MS-DOS や Windows 内部では , 上記のよ うなフルバスファイル名のうちでドライプ 名を省いた場合は , カレントドライプを指 定したことになります。同じようにディレ クトリ名を省いた場合は , カレントディレ クトリを指定したことになります。実際に はフルバスファイル名 ( もしくはフルバス 名 ) を表すときにディレクトリ名だけを省 くことはありません。 これで基礎ができたので , 最初に投げか けた , MS - DOS プロンプトで実行できた実 行ファイルと実行できなかった実行ファイ ルの謎を解明していきます。 ディレクトリ・ファイルが何百もあり , さらに XYZ. EXE が複数あったら , 他人が自 バスの設定 26 C MAGAZINE 2 1 4 分の思っている XYZ. EXE を見つけて実行で きるとは限りません。 MS-DOS/Windows で も同じです。 MS-DOS/Windows は融通が きかず , 指示されたことしかしません。ど こにあるかわからない XYZ. EXE を自動的に 見つけて実行することはしないのです。そ して MS-DOS/Windows はカレントをいつも 注目しています。ここまで書けば , 勘のい い方ならおわかりでしよう。フルバスファ イル名で XYZ. EXE を指定するか , カレント ディレクトリを XYZ. EXE のあるディレクト リに移動させればいいのです。 MS-DOS プロンプトで実行させるには , C : *APP%F I LE*DOC*XYZ . EXE と打ち込んで , キーを押します。最 初の例の CD-ROM ドライプにある LHASAOI 7. EXE を実行するには , CD-ROM ドライプ が D ドライプなら , D : *TOOLS*LHASA*LHASA 017 . EXE と打ち込みます。 LHASA017. EXE が CD-ROM に存在すると いうこともあり , いつも実行するわけでは ないので問題にはならないかもしれません。 しかし , XYZ. EXE がよく使うツールだとし たらどうでしよう ? なおここでの説明は , ートカットファイルを作って実行すれ シ - ヨ ばいい , という次元の話とはちょっと違う ということをご了承ください。 XYZ. EXE という実行ファイルがどのディ レクトリに存在するのかということを , MS- DOS/Windows に教えてあげます。この作 業を , パスを設定するなどといいます ( パ スを通すなどともいう ) 。 バスの設定方法 まずは Windows 95 / 98 です。 C ドライプ のルートディレクトリに AUTOEXEC. BAT というファイルがあります。これをエディ タ ( なければメモ帳 ) で開いてみましよう。 なおメモ帳でファイルを開くときの「開く」 ダイアログボックスでは , 最初は拡張子が IXT のものしか見えないようになっていま す。いちばん下の「ファイル名の種類 : 」で 「すべてのファイル」を選びましよう。 PATH=C : %APP*F I LEDOC てメモ帳を終了してください。 らなければ以下のように記述して , 保存し という 1 行は見つかりましたか ? PATH= AUTOEXEC. BAT ファイルに 見つか ロバティ ] メニューを選択します。「システ ビュータを右クリックして表示される [ プ ールを使います。デスクトップのマイコン と同様 , AUTOEXEC. BAT は存在せず , ッ 最後に Windows 2000 です。 Windows Me を実行することができます。 トディレクトリがどこであっても XYZ. EXE を再起動すればパスの指定ができ , カレン さらに亟ボタンをクリックして W ⅲ dows を追加して一ボタンをクリックします。 ー C : %APP*FILE*DOC の値」欄の最後に 示される「変数の編集」ウインドウの「変数 択して [ ] ボタンをクリックします。表 数」の列に PATH という項目があるので , 選 たら , [ 環境 ] タブを開きます。そこに「変 ム設定ユーティリティ」ウインドウが開い ィリティ ] メニューを選択します。「システ す。その [ ツール ] → [ システム設定ューテ と「ヘルプとサポート」ウインドウが開きま ステム情報 ] メニューを選択します。する → [ アクセサリ ] → [ システムツール ] → [ シ います。スタートボタンから [ プログラム ] WindowsMe に用意されているツールを使 ても使われていない可能性があります ) 。 には , AUTOEXEC. BAT がありません ( あっ 次に W1ndows Me です。 Windows Me っても XYZ. EXE を実行できます。 ができ , カレントディレクトリがどこであ Wmdows 95 / 98 を再起動すればパスの指定 ほかのパス名との区切りです。これで , ( セミコロン ) を忘れないでください。 ; は , て , フ回設定するパス名の前に PATH= ほかの / ヾスー C : %APP%FILE*DOC します。 見つかったならば , その行の最後に追加

7. 月刊 C MAGAZINE 2001年4月号

配列言語 メ五ロ ス - = -0 第七十六語 学千 きだあきら を求め , その絶対値の中で最大の値を , そ 並列指向の ZPL の画素位置に関する勾配の近似とする ( 古 典的な ) 方法を採用している。 このような処理を施すと , 画像的な意味 ZPL は , 米国ワシントン大学で 10 年近く としては「エッジ抽出」という作業になる。 前から開発されてきたプログラム言語で , たとえば , Fig. 1 のような元画像をⅱ stl に 仕様上の大きな特徴は , many at a time 言語 与えると , 結果は Fig. 2 のようになる ( この の一種だという点にある。 manyata ⅱ me と は , 言語のソース上にて単独の操作により , ような処理なら , GIMP や Photosh 叩などを 使えばわざわざプログラムするまでもない 実際には多数のデータの演算が行われるよ が , それはさておこう ) 。なお , List 1 のプ うな一連の言語を指す。同種の言語として は , たとえば APL をはじめとして , J , S , ログラムは , 入力は PGM(Portable Gray Ma p) というファイルフォーマットを少し修正 R, octave などが多数あるが , そうしたなか で ZPL の特徴は , 最初からコンパイラ言語 バースエンジニアリングの禁止を含めた独 したものを与える必要がある。出力はその 自のライセンスを用いている。しかし , 非 として設計されているということと , 並列 まま PGM になっている。 商用の目的に対しては無料で利用できる。 ハードウェア上で効率よく実行できること 領域とその操作 List1 には , ZPL のプログラム例を示した。 を目標にしていることである。ただし , ZPL のコンパイラは並列ハードウェア以外 このプログラムは , 与えられた画像の勾配 ( gradient ) を求めるためのものである。専 今回は , ZPL 最大の特徴である領域の操 にも実装されていて , シングル CPU のマシ 門的にいえば , 画像の各点について , 偏微 作 ( の一部 ) のみをピックアップして説明し ンでも動作させることが可能である。 分値が最大値をとる方向広は , arctan((a たい。最初のポイントは region 定義である。 まず , ZPL 処理系の実装の説明をしてお f/ a y) / ( a f/ a x) ) であり , その大きさは 「一」で始まるコメント行と空白行を除外する く。現在 ZPL はバイナリのみ配布されてい ・ - ( てびレ爻戸夲てゑレの・ⅵ歹と定められ , そ て , 主要な UN Ⅸプラットホーム ( X86 用の と , List 1 の 12 行目がそれに当たる。この領 Linux や FreeBSD を含む ) については非並列 域定義は 1.. n , 1.. m という 2 次元領域を定義 の向きと大きさを持つべクトルを gradient という ( ここで読むのを止めないでほしい ) 。 ハードウェア版を含めてリリースされてい して , それに IM という領域名を与えている ただし , デジタル画像では通常何らかの差 ( 領域は 1 次元以上何次元でも定義可能 ) 。こ る。ライセンシングボリシーは , バイナリ 分式でこれを近似する。 List1 では , 着目画 こで , n と m はともに変数である。この場 のみの配布ということを見てもわかるよう に , あまりオープンにはなっておらず , リ 素に対して , 上下左右の隣接 4 画素との差 合 , 実際の領域のサイズは実行時の変数の 与えられた画像の勾配を求める ZPL のプログラム例 List 1 List 28 : 29 : procedure GetImageSize(infile:fiIe) :integer; var dim : integer ー 30 : 31 : begin read(infile,dim); 32 : writeln(zerr, "Read size = 33 : return dim ー 34 : 35 : end; 36 : 37 : procedure Grad4nbr ( 38 : var outfile : file; 39 : begin 40 : [IMI read(zin, A); 41 : [north Of IM] reflect 42 : 43 : [east Of IM] ref lect A; [west Of IM] reflect 44 : [south of IMI reflect 46 : = 255 - max(max(abs(A - A@noてヒ h ) , [IM] abs(A - A@east) ) , 48 : max(abs(A - A@west) , 49 : abs(A - A@south) ) 50 : 51 : outfile : = open(ofname, ” w ” outlmage(outfile, B); 53 : close(outfile); 54 : 55 : end; 1 : - SampIe ZPL program written by Akira Kida 2 : 3 : program Grad4nbr; 4 : 5 : p て OtOt 、 rpe Get ImageSize ( inf 土ー e : fi ー e ) : integer ー 6 : 7 : conf ig var : integer = GetImageSize(zin); 8 : : integer = GetImageSize(zin); 9 : ofname : string = ″ ou セ pu し pnm"; 10 : 11 : 12 : region A, B : [ IM] integer; 13 : 14 : 15 : direction north = ト 1 , 01; east = [ 0 , 11; 16 : [ 0 广 1 17 : west = south = [ 1 , 01; 18 : 19 : - Fake ASCII format of PGM(Portable Gray Map) 20 : 21 : procedure OutImage(outfiIe:file; var X : [ IMl integer); 22 : begin writeln(outfile, ” P2 ” writeln(outfile, m, 24 : writeln(outfile, 255L writeln(outfile, X); [ Ⅲ ] 26 : 27 : end; , dim 1 8 c MAGAZINE 2001 4

8. 月刊 C MAGAZINE 2001年4月号

Fig. 5 クオータニオンの加減乗算 ( a ) 例となる数式 ql = 十も i 十 J = 肥 2 十も i 十 ) ・ 2j 十 z 講 ( b ) 加減算 ql+q = 0 町 + 朝 + + も ) i + 伝ザ万 + は + z 謎 ql ー 2 = 0 町一吶 + ( も一も ) i + づ万 + 6 ー z 謎 ( d ) 乗算 sq = s 肥十 & 十当ノ十 sz 為 ( c ) スカラー倍 逆クオータニオンを求めるために オンの乗算で行います。 に , クオータニオンの除算も逆クオ =@匙2ー町ら , ル画 + ル 2 ら + ら XV2) ー 4 = 朝广肥 2 , ら一朝 ql 十リ2=@げル2 , 十ら ) (b)Fig. 5 の加減算に , を用いた例 = く x , 鰺 z> ( a ) 3 次べクト丿いを用いた表記 べクトルを用いた表記方法 +@声2+肥2 + も ) ' 2 ー ) 2 十 0 町十ル 2 十 . X2 ー声 2 +@き2 + 肥げ ) ド 2 ー名 2 ) i ql =@卩む2 ーもも一 ) ・げ 2 ー z 声 2 ) (e) ( d ) をれえを用いて整理 + もん 0 + 2i + z い j + に + J 肥 2 十お 2i + の ' J 十第 十工き肥 2 十 X ー壟十ーり・ 2J 十工 Z = 7 町 2 十ル壟十ル 2J 十ル卩 2 ータニ いく つかの概念の説明を先にしておきましよう。 まずは , 絶対値です。これは複素数のとき に触れたようにべクトルと同じように求め ることができます (Fig. 7- (a) ) 。直感どお りですね。もちろん答えはスカラー ( 実数 ) になります。いわば長さを求めることがで きたので , 正規化べクトルのような正規化 クオータニオン (unit quaternion) というも のも考えられます。スカラー倍が可能であ るなら , スカラー除算も当然可能になるの で , Fig. 7- (b) のように長さが 1 のクオータ ニオンを作ることができます。この長さ 1 10 C MAGAZINE 2001 4 Fig. 7 逆クオータニオン ( a ) 絶対値 ( b ) 正規化クオータニオン rm 浦記 ( の = イ ( c ) 共役 ( d ) クオータ二オンと共役を掛け合わせる = 肥十・ ( e ) 同じもので割る / 2 = 1 ( f ) 逆クオータニオンの数式 4 4 / 2 が 1 のクオータニオン , あとで回転のこと を考える際に非常に重要になります。 また , 共役 (conjugate) というものも知 っておきましよう。複素数にも存在します が , 共役とはスカラー部分以外にマイナス を掛けたクオータニオンのことを指します (Fig. 7-(c))0 名前まで与えられているだけ あって , この共役にはいろいろとおもしろ い性質があります。たとえばクオータニオ ンとその共役を足せばスカラー部分が残る というのもそうですが , もっと利用価値の 高いものとしてクオータニオンとその共役 を掛け合わせてみましよう (Fig. 7-(d))0 れも答えがスカラーになります。それだけ ではなく長さの 2 乗なんていうできすぎた 答えが手に入りました。 そこで , ちょっとひねって Fig. 7- (e) のよ うな式を考えてみましよう。同じもので割 っているので , 答えは 1 になるのがあたり まえですが , この式はに何かを乗算する と 1 になるということも表しています。つ こで掛けているものが求めている まり , 逆クオータニオンです。 Fig. 7- (f) のように 逆クオータニオンは共役を絶対値の 2 乗で 割ったものになります。また , このクオー タニオンが正規化クオータニオンだった 場合 , 逆クオータニオンは共役そのものに なります。 逆クオータニオンが手に入って , 除算が 行えるようになりましたので , 不思議な i , j, から生まれた演算の仕組みはここまで になります。それにしても思っていたより 難しいところはありませんでしたよね。内 積や外積のほうがよっぱど理解しにくい 気がします。 回転との関係 それではいよいよ 3D プログラミングの 話題 , 回転の説明に進みます。クオータニ オンが回転をどう表すのか , またどう取り 扱うのかを見ていきます。 回転軸表現 いざクオータニオンでの回転に進む・・・ その前に , 回転軸表現 (Axis-angIe represe ntation) の説明をしておきましよう。問題 の多かったオイラー角表現では , X ) 努各軸 における回転角度によってオプジェクトの 姿勢を表現していましたが , 回転軸表現は 回転軸となるべクトルと , 回転角度によっ て姿勢の表現を行います。努軸にとらわ れない , 自由な軸を中心に回転させること から , 自由軸回転あるいは任意軸回転とも 呼ばれます。 ここで Fig. 8 の図を見ながら考えていき ましよう。回転軸となる正規化べクトルを れとして角度″の回転を行うとします。回 転の対象となる点を指すべクトルを r とし て回転後のべクトルをドとします。 こで話を簡単にするために , べクトル ′を 2 つのべクトルに分解することを考えま す。回転軸″に沿った平行成分べクトルル と , れに対して垂直に回転面を構成する垂 直成分なに分割します。べクトル成分の分 解といえば内積の登場です。 Fig. 9- ( a ) のよ うに分割することによって , べクトルの回

9. 月刊 C MAGAZINE 2001年4月号

困ったときの 解決策はどこにある ? 今は本誌を読むほとん きませんでしたが Fig. 3 開発者が書いた言語の教科書 ( 邦訳があるもの ) どの読者が使用可能になっているでしよう。 「プログラミング言語 C ( 第 2 版 ) 」 , カーニハン & リッチー , 共立出版 インターネットは便利なものです。検索 「プログラミング言語 C + + ( 第 3 版 ) 」 , ストラウストラップ , アジソン・ウェスレイ 工ンジンや WWW によるリンクなど , これ 「 Java 言語仕様 ( 第 2 版 ) 」 , ゴズリン他 , ピアソン・エテュケーション Java らの利便性は本をはるかに上回ります。で 「プログラミング Pe 「 l( 改訂版 ) 」 , LarryWall 他 , オライリー Perl は , インターネットによる情報の収集が本 『プログラミング言語 AWK 』 , Aho 他 , トッパン AWK による情報収集にとって代わるかというと , そうでもないのですね。 くらか用意しておきましよう。 まず , ほしい情報がネット上になく , 本 ういう「なじむ」感覚を味わったことはあり でしか手に入らないことがあります。これ ません。 1 次情報を意識せよ これらの問題は将来的には解決されるで は当然で , なにしろインターネットの情報 しかし「本を買え」といっても , 見境なく しよう。しかし今はまだ , 本に大きな利点 はほとんどが無料であり , タダのものに労 買っていては意味がありません。定食屋の 力をかけるには何か強い動機が必要です。 があります。電子情報にのみに頼って済ま せようとすると , 少なくともあと何年かの メニューを見ると , ご飯に味噌汁に漬物に 個人のサイトの場合 , それは使命感であっ メインの料理があて , おひたしか煮物カ : 間は大きなハンデを負うことになります。 たりサービス精神だったりします。また , ・・といった感じになっています 1 品付く・・ 企業が自分の技術を普及させるために技術 が , 本を買うときにも取り合わせを考えな 情報を公開することがあります。たとえば ければいけません。 JavaSoft では , Java 言語仕様や Java チュート 取り合わせの 1 っとして , まずそろえた 本による情報収集の第 1 歩はまず , 本を リアルなど , 本をまるごとネット上で公開 いのは一次資料です。「 1 次資料」という言 買うことです。情報収集の方法なんて言い しています。しかしそうでない場合は , 著 葉を聞いたことがあるでしようか ? たと 者が「公開するメリットがない」と判断して つつ本を買いなさいというのはあまりにあ えば歴史の研究にとっては , ロゼッタスト たりまえすぎるようですが , 本当のことで 見送られることになります。 ーンとか , 敦煌文書とか , ああいうのが 1 もう 1 つの理由は , 本のほうが圧倒的に す。 広義の「本」には書籍と雑誌が含まれま 次情報・ 1 次資料です。 読みやすいことです。本は片手で読めるの プログラミングの分野での 1 次資料は , C す。書籍は情報をまとめて得ることができ に対し , ディスプレイを片手で持ち上げて 言語のように公的に認められた規格がある る反面 , 掲載範囲が限られており , 情報が 見るにはそうとうな筋力を要します。まあ 場合 , その規格ということになるでしよう。 古い場合があります。雑誌はニュース性に それは置いたとしても , 本を見るのとディ また , 言語の開発者かそれに近い人が書い スプレイを見るのとでは目の疲れ方がずい すぐれ , いろいろな事項が書いてあるので た教科書も , 1 次資料といっていいでしょ 知識を広げるのには役立つものの , リファ ぶん違います。これはかなり大事なことで う。各言語に 1 冊程度はそういう本がある す。また , 一度に読める文字数にも差があ レンスとしては不便です。 これは個人的に言いづらいのですが , 『 C ものです。いくつかの例を Fig. 3 に示して ります。一般的なディスプレイに通常の大 おきます。 きさのフォントを使って表示できる文字数 MAGAZINE 』を購読しているから書籍を買 1 次資料をそろえろと言う理由は , 時間 は , 本誌 1 ページの半分くらいでしよう。普 わないでいいかといえば , そうはならない を節約するためと , 自信を持っためです。 通は画面全部に文字を表示することはない と思います。本誌が役に立たないという意 勉強していて , あることでつまずいたとし ので , もっと少なくなります。 味ではなく , 長所短所があり相補的に使う ます。そのとき , 1 次資料を持っている人 こういった視覚的特性のほかに , ちょっ べきものだということです。 と持っていない人では , 解決にかかる時間 と表現が難しいのだけれど , 手になじむ使 さて , 本を買うにはお金がかかります。 が違うのです。 1 次資料がないと最後まで いやすさが本にはあります。机の横に置い コンピュータ関係の書籍は安くて二千円前 「この解決法でいいのだろうか」という不安 後であり , 高いものは五千円以上。この負 て始終使っている本なら , 調べたいことが 担は , とくに学生さんの場合 , かなり痛い がつきまとい , 何度も調べ直したりしてし あったとき「たしかあのへんのページにあ まいます。たぶんいいと思っても自信が持 出費だとは思います。 ったな・・・・・」と , すぐに引くことができま す。ページの位置を指が覚えているのです。 ですが身も蓋もないことを言えば「かか てません。結局 , 時間のムダとなります。 電子的情報に関して , 少なくとも筆者はそ るものはかかる」のです。そう覚悟して , い 具体的には , コンパイラの挙動が不正だっ 本を買うこと 特集プログラミング入門困ったときの解決策はどこにある ? 21

10. 月刊 C MAGAZINE 2001年4月号

List 1 とまったく同じですが , 領域内外の 判断をする部分で複数画素を見るように変 更する必要があります。また , List 1 では 近傍の画素を調べるところで同じような文 が並んでいて美しくないので , ループ処理 でまとめていますが , 処理の流れ自体は変 わりません。 List1 から変更された部分を 抜き出したものが List 2 です。 関数 in ー region の部分に注目してくださ い。この関数は , 画素が領域内であるか否 かを判別する関数です。 List 1 では注目画 素の画素値のみで判断していたのを , その 近傍の画素についても画素値のチェックを 行い , すべての画素が条件を満たす場合の み領域内とみなすようにしています。 1 つ ずつの画素が領域内の条件を満たすか否か absi( (int)firstcol.citem. g ー (int)col.citem. g)>beta Ⅱ absi( (int)firstcol . citem. b - (int)col.citem. b)>beta) ( を判別するのは in ー regionl という関数です が , これは List 1 における関数 in region と 同じ内容です。 List2 は , 注目画素についてその近傍を チェックしにいくので , List 1 に比べて同 じ画素を調べる回数がさらに増えることに なります。このあたりに効率化の余地があ るかもしれませんが , 今回はそこまで行っ ていません。 それぞれのプログラムによる処理の例を 付録 CD-ROM に収録しました (rgrow. htm 1)0 元画像は境界上に 1 画素ぶんの隙間が ある画像になっていますが , List 2 のプロ グラムで処理を行うと , この部分から処理 が漏れてしまう現象が起きていないことが 確認できます。 / * 土 n セ mask; 0 List 1 まとめ 今回は任意の領域内の塗りつぶし処理の 1 っとしてリージョングローイングを紹介 しましたが , 一般的には画像中から興味の ある領域を抽出する目的でリージョングロ ーイングを利用することが多いと思いま す。その場合には , 今回紹介したような単 純なパラメータだけでは適切な処理が行え ないケースがほとんどです。望みどおりの 結果を得るためには領域の性質に合わせて 適切な条件判断方法を考える必要がありま す。また , リージョングローイングでは領 域境界上の微小な切れから処理が領域外部 に漏れてしまう問題が発生する可能性があ 0 List 1 if(in—region(edt,xx-l,yy,now) ) ( PMsStartPset(edt,xx-l , め ' PMsPSet(edt,xx-I'YY'0); if( !set—buf(edt,xx-l,yy)) ( MessageBox(edt->hwnd,"Buffer ove て″ return ENDDRAW ー PMsSetDrawFlag(edt,xx-1,yy,TRUE); udcod(xx-l,yy); newf Iag=TRUE; if(in-region(edt,xx,yy 十 l,now) ) { PMsStartPset ( edt , xx , ) ッ十 1 PMsPSet(edt,xx,yy 十 1,0嶹 if( !set-buf(edt,xx,yy + 1)) { MessageBox(edt->hwnd, "Buffer over return ENDDRAW; PMsSetDrawFIag(edt,xx,yy 十 I,TRUE); udcod ( ′十 1 newf ー ag=TRUE ー 土 f ( 土 n ー region ( + 1 , , now ) ) { PMsStartPset ( edt , xx 十 1 , yy PMsPSet(edt,xx 十 1,)ツ,0レ if( !set-buf(edt,xx 十 1,艸)) { MessageBox(edt->hwnd, "Buffer over return ENDDRAW ー PMsSetDrawFlag(edt,xx 十 1,ゝツ,でRUE潺 udcod ( 十 1 , め , newf Iag=TRUE; 土 f ( tcon に = = 200 ) { PMsUpdateImageWindow(edt,dx1,dy1,dx2,dy2); E てて” , ー OK ,"Err",MB—OK); , ” E てて″田一 OK dx1=dx2=-1; dy1=dy2=-1; tcont=0 ー /*if( !newflag) tailp--;*/ tcont 十十一 PMsUpdateImageWindow(edt,dx1,dy1,dx2,dy2); 0 int set—buf ( Edtwin *edt, int x , int y ) Pix32 nei; return ENDDRAW ー setcursor ( 引 dcur mask=PMsGetMask ( edt , x Ⅳ if(mask&MASK-FLAG) return TRUE;*/ sbufx[headp]=x; sbufy[headpl=y; cbuf[headpl=nei; //if(taiIp==BUF—SIZE-1) return FALSE; headp=(headp 十 I)%BUF-SIZE; return TRUE ー int in—region ( EdtWin *edt , 土北 x は北 y , P 土 X32 col ) 土北 mask; if(PMsGetCoIorOnImageGIobaI (edt,x,y,&nei)==FALSE) return FALSE ー mask=PMsGetMask ( edt , x , y if ( mask&MASK—FLAG ) return FALSE; if(absi( (int)nei. citem. て - (int)col.citem. r)>difv Ⅱ absi( (int)nei. citem. g - (int)col.citem. g)>difv Ⅱ absi( (int)nei. citem. b - (int)col.citem. b)>difv) { if ( Y>dy2 ) dy2=y; if ( Y<dy1 ) dyl=y; if(x>dx2) dx2=x; if ( X<dx1 ) 1 = return ー dy1=dy2=y; dx1=dx2=x; 土 f ( 2 く 0 & & dy2 く 0 ) { int udcod ( 土 n し x , int y ) return TRUE ー return FALSE ー if(absi( (int)firstcol . citem. て - (int)col.citem. r)>beta Ⅱ return FALSE; return ENDDRAW ー 土 n セ FAR WINAPI PMcCanceIOne(EdtWin *edt,int x,int y) 104 C MAGAZINE 2001 4