プリント基板設計・シミュレーション

TOP > アポロレポート > コラム > 第16回 プログラミングについて 『回す話』
コラム
2022/09/16

第16回 プログラミングについて 『回す話』

アポロレポート

『回す話』

 

回す話。今回は図形を回すことについて考えてみましょう。図形の回転といえば2次 元や3次元で図形を回転させて表示することを思い浮かべるかとおもいますが、そうい う場面で使用する回転はごく部分的な使い方です。実際には様々な図形の計算を行なうときに回転は解を簡単に得るための有効な手段なのです。

 

 回転の座標変換は確か高校の算数で習ったという記憶があるのですが、それをもとに して作った座票値を回転する関数の例を紹介します。

 

 #include <math.h>

 

 void rotation(xc,yc,rot,xsrc,ysrc,*xret,*yret)

  double xc,yc,rot;

  double xsrc, ysrc;

  double *xret,*yret;

 {

  double cc,ss;

 

  cc=cos(-rot);

  ss=sin(-rot);

 

  xsrc-=xc;

  ysrc-=yc;

 

  *xret= xsrc*cc+ysrc*ss+xc;

  *yret= -xsrc*ss+ysrc*cc+yc;

 }

 

 xc、yc は回転の中心座標、rot は回転角度(単位=ラジアン)、xsrc、ysrc は回転する前の座標、xret、yret は回転後の座票値を返す引数です。

 

 この関数自体はとりたてて説明するほどのものではありません。何かの参考にでもして下さい。

 

 いま、直線が1本、点が1つあったとします。点が直線の進行方向に対して右側にあるのか、左側にあるのか、それとも直線の延長線上にあるのかを調べる関数を作りたいときに、以前お話しした複素数を使って実現するのも1つの手段です。それ以外で単純に求めるには回転を使うのです。

 線分P1-P2の角度をA度とすると、点の位置PをP1を中心にして-A度回転させます。直線は回転させる必要はありません。すると、回転後の点の位置P´は相対的には同じく回転した直線P1´-P2´と同じ位置になります。また回転後の直線はX軸に平行になっていますので、P1のY座標とP´のY座標の関係を調べるだけで済むことになります。

 

 int get_line_point_relation(x1,y1,x2,y2,xp,yp)

 double x1,y1,x2,y2;

 double xp,yp;

 {

  double a;

 

  angle(x1,y1,x2,y2,&a);   /* 直線の角度を求める関数 */

 

  rotation(x1,y1,-a,xp,yp,&xp,&yp);

 

  if(yp>y1+0.0001)return -1; /* 左側 */

  if(yp<y1-0.0001)return 1; /* 右側 */

 

  return 0;          /* 延長線上 */

 }

 

 と表現することができます。またその距離を求めるは上記の例で回転後の yp と y1の差の絶対値で求められます。点からの垂線の端点の座標は回転後の xp と y1 の座標を再び a で回転すれば求められます。

 

 3点を通る円弧の最小座標と最大座標を求めるときにも回転は大活躍します。実は10数年以上も古い話になるのですが、この値を求める関数を書くのに四苦八苦した経験があるのです。紙の上で計算式を導くのもかなり大がかりな作業で、これをプログラムにするのもバグがなくなるまでかなり時間がかかった記憶があります。実際には数年間使ってバグが出たり、実行スピードが上がらなかったりしたものです。回転を使うアイデアを思い付いたのは10年ぐらい経過してからのことでした。

 

 さてこの円弧の最小最大を求めるには回転をどう利用すればいいのでしょうか。やはり単純に回転をして結果が出るものではなく、ちょっとしたお膳立てが必要になります。まず図1を見て下さい。

 円弧はP1、P2、P3を通過しています。円弧が全円だったとして円の最小最大位置となる4つの点(Cxm、Cxx、Cym、Cyx)を追加して考えます。

   

 次にこの円弧を弦P1-P3がX軸と平行になるようにP1を中心に回転させると図2になります。

  

 回転させた理由は新たに追加した4つの点のなかで円弧と関係のないものを除外するためです。図2で円弧の開始点P1のY座標よりも下にある点は除外しても良いことは分りますね(円弧の回転方向が逆のときはP1のY座標よりも上の点を除外します)。

さらに円弧の通過点は意味がないのでこれも除外します。

 

 関係のない点を除外した後、ふたたび円弧の弦が元の角度になるように残った点を回転すると図3になります。

  

 こうなると後はどうすればいいかは分ると思います。残った点の最小最大を求めればいいことになります。

 

 グラフィックのエディタなどを作っていると、下の図のように斜めになった文字列データをマウスで1ポイントのみを指定して選択したいことがあります。実際には文字列の最大外形の矩形(図では破線で示してある)内にマウスで指定されたポイントが入っているかいないかで判断するのですが、このまま真面目に計算すると気の遠くなるような計算をしなければなりません。

 

  

 そこで回転の登場となる訳です。文字列を0度の角度になるように矩形とマウスで指定したポイントをを回転させます。

 

 

      

 こうなると一目瞭然。どのようにプログラムを書けばいいかはすぐに分りますね。

 

 閉図形(円や矩形やポリゴン)にハッチングをかけるときなどにも回転を利用すると簡単に表現することができます。ハッチングが0度とか90度の単一方向のハッチングのときには問題はないのですが、45度と135度のハッチングを重ねたいとか、任意の角度のものを重ねたいとかになってくると問題は面倒になってきます。

 こういうときにも回転を使います。例えば45度のハッチングをかけるときには図形を-45度回転させて0度方向のハッチングの計算を行ない、算出されたラインを再び45度回転させるのです。このようにすればハッチングの計算自体も簡単になる可能性があります。

 

 回転が目的となる場面は実際のアプリケーションではごく希にしかありません。ほとんどの場面では回転は目的に到達するための手段でしかないのです。確かに裏方の地味な存在なのですが、正面から目的に向って解決しようとすると複雑怪奇なプログラムになるものが、この裏方の力を借りると拍子抜けするほど簡単になってしまうことがあるのです。

 今回は回転の一例を紹介しましたが、回転が登場する場面は以外に多いものです。どんなプログラムを書くときでもそうですが、できる限り単純に解を求めるように工夫して下さい。むずかしく書かれたプログラムが喜ばれるというものではありません。単純でスッキリと書いてあるものの方が、速度の向上にも、保守のしやすさにも大きく貢献してくれるでしょう。

 

 ではまた次回。


そのお悩み、
アポロ技研に話してみませんか?

アポロ技研でワンランク上の物創りへ!
そのお悩み、アポロ技研に話してみませんか?