Indexへ
(32089)//【32090】→(32104)
------------------------
【タイトル】外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32090 (*)
【 日時 】08/11/26 14:15
【 発言者 】hide

ユーザ定義関数function未実行の回避の仕方
外部変形を作成してますが、下記ユーザ定義関数を使って交点計算を実行してみると、一方の線が鉛直線である時だけ、思わぬところへ点が書き出されます。

 また、これを回避するため、原点基準で座標回転移動を行い、鉛直線を回避して交点計算を行なって仮座標を算出し、更に元方向へ回転して戻して本座標を算出と試みたのですが、未実行となってしまいます。
鉛直線の無い場合は、うまく実行してくれます。
鉛直線が発生した場合の傾きの処理はどうしたらよいですか。
御意見よろしくお願いします。


#2線4点交点座標 X=
function koutenx(x11,y11,x12,y12,x21,y21,x22,y22){
if(x11==x12 && x21!=x22){
return x11
            }
else{

if(x11!=x12 && x21==x22){
return x21
            }
  else{
if(x11!=x12 && x21!=x22){
m1=(y12-y11)/(x12-x11);
m2=(y22-y21)/(x22-x21);
return (y21-y11+m1*x11-m2*x21)/(m1-m2);
            }
     }
   }
                         }

#2線4点交点座標 Y=
function kouteny(x11,y11,x12,y12,x21,y21,x22,y22){
if(x21==x22){
#a=atan2((y12-y11),(x12-x11))
#return y11-(x11-x21)*(sin(a)/cos(a))
m1=(y12-y11)/(x12-x11);
return y12+m1*(x21-x12);
            }
else{
if(x11==x12){
#atan2((y22-y21),(x22-x21))
#return y21-(x21-x11)*(sin(a)/cos(a))
m2=(y22-y21)/(x22-x21);
return y22+m2*(x11-x22);
            }
  else{
if(x12!=x11 && x22!=x21){
m1=(y12-y11)/(x12-x11);
m2=(y22-y21)/(x22-x21);
x=(y21-y11+m1*x11-m2*x21)/(m1-m2);
return y11+m1*(x-x11);
            }
     }
   }
                         }

#回転座標 X=
#function turnx(x1,y1,n){
#a1=atan2(y1,x1)
#return x1/cos(a1)*cos(a1+n)
#y=x1/cos(a1)*sin(a1+n)
#            }
#
#回転座標 Y=
#function turny(x1,y1,n){
#a1=atan2(y1,x1)
#x=x1/cos(a1)*cos(a1+n)
#return x1/cos(a1)*sin(a1+n)
#            }


Indexへ
(32090)←【32104】→(32112)
------------------------
【タイトル】Re(1):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32104 (32090)
【 日時 】08/11/27 12:33
【 発言者 】通りすがり

線(x11,y11)-(x12,y12)と線(x21,y21)-(x22,y22)の交点を求めるなら
私ならこう書きます。ただし両線は平行でない。

m1 = (x11 == x12) ? 1000000000 : (y11 - y12) / (x11 - x12)
m2 = (x21 == x22) ? 1000000000 : (y21 - y22) / (x21 - x22)
l_cp(x11, y11, m1, x21, y21, m2, re)
xp = re[1]; yp = re[2]

func l_cp(x1, y1, m1, x2, y2, m2, re) {    # y = m1 * (x - x1) + y1
    re[1] = (   (y1 - m1 * x1) -   (y2 - m2 * x2)) / (m2 - m1)
    re[2] = (m2 * (y1 - m1 * x1) - m1 * (y2 - m2 * x2)) / (m2 - m1)
}


Indexへ
(32104)←【32112】→(32115)
------------------------
【タイトル】Re(1):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32112 (32090)
【 日時 】08/11/27 18:07
【 発言者 】KITI

hideさん こんばんは、KITIと申します。

最近 awkを使っていないので具体策ではないのですが・・

KITIの場合 線Aと線Bの交点を考える時

線Aが垂直な時   -- 線Bが垂直な場合
          -- 線Bが水平な場合
          -- 線Bが斜めな場合

線Aが水平な時   -- 線Bが垂直な場合
          -- 線Bが水平な場合
          -- 線Bが斜めな場合

線Aが斜めな時   -- 線Bが垂直な場合
          -- 線Bが水平な場合
          -- 線Bが斜めな場合

以上9通りのケースが 処理されているかチェックします。

どこかで 割算の分母が0になっているとこは ないですか?
出てきた交点は 線A上にありますか?(延長線上ではないですか?)

参考になれば 幸いです。

   デワデワ   広島のKITIより


Indexへ
(32112)←【32115】→(32135)
------------------------
【タイトル】Re(1):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32115 (32090)
【 日時 】08/11/27 21:09
【 発言者 】Kazuo Miyake qqza3hq89@aioros.ocn.ne.jp

▼hideさん:
>ユーザ定義関数function未実行の回避の仕方
>外部変形を作成してますが、下記ユーザ定義関数を使って交点計算を実行してみると、一方の線が鉛直線である時だけ、思わぬところへ点が書き出されます。
>
> また、これを回避するため、原点基準で座標回転移動を行い、鉛直線を回避して交点計算を行なって仮座標を算出し、更に元方向へ回転して戻して本座標を算出と試みたのですが、未実行となってしまいます。
>鉛直線の無い場合は、うまく実行してくれます。
>鉛直線が発生した場合の傾きの処理はどうしたらよいですか。
>御意見よろしくお願いします。
>
>
>#2線4点交点座標 X=
>function koutenx(x11,y11,x12,y12,x21,y21,x22,y22){
>if(x11==x12 && x21!=x22){
>return x11
>            }
>else{
>
>if(x11!=x12 && x21==x22){
>return x21
>            }
>  else{
>if(x11!=x12 && x21!=x22){
>m1=(y12-y11)/(x12-x11);
>m2=(y22-y21)/(x22-x21);
>return (y21-y11+m1*x11-m2*x21)/(m1-m2);
>            }
>     }
>   }
>                         }
>
>#2線4点交点座標 Y=
>function kouteny(x11,y11,x12,y12,x21,y21,x22,y22){
>if(x21==x22){
>#a=atan2((y12-y11),(x12-x11))
>#return y11-(x11-x21)*(sin(a)/cos(a))
>m1=(y12-y11)/(x12-x11);
>return y12+m1*(x21-x12);
>            }
>else{
>if(x11==x12){
>#atan2((y22-y21),(x22-x21))
>#return y21-(x21-x11)*(sin(a)/cos(a))
>m2=(y22-y21)/(x22-x21);
>return y22+m2*(x11-x22);
>            }
>  else{
>if(x12!=x11 && x22!=x21){
>m1=(y12-y11)/(x12-x11);
>m2=(y22-y21)/(x22-x21);
>x=(y21-y11+m1*x11-m2*x21)/(m1-m2);
>return y11+m1*(x-x11);
>            }
>     }
>   }
>                         }
>
>#回転座標 X=
>#function turnx(x1,y1,n){
>#a1=atan2(y1,x1)
>#return x1/cos(a1)*cos(a1+n)
>#y=x1/cos(a1)*sin(a1+n)
>#            }
>#
>#回転座標 Y=
>#function turny(x1,y1,n){
>#a1=atan2(y1,x1)
>#x=x1/cos(a1)*cos(a1+n)
>#return x1/cos(a1)*sin(a1+n)
>#            }

 鉛直線に限って計算できないのであれば いんちきくさいので
すが X 座標は計算する必要もないので、別ルーチンで強制的に
計算してもよいのではと思います。

 また、ひょっとすると
鉛直線の角度が90°ではなく89.999・・・9°や
90.000・・・1°となっている可能性もあると思います。

 私も awkの外部変形プログラムを作ったことがあります。
 そのときは
数学の教科書のように2直線を
 a1*x+b1*y+c1=0
 a2*x+b2*y+c2=0
として、交点を
 X=(c1*b2-c2*b1)/A
 Y=(a1*c2-a2*c1)/A
 A=a1*b2-a2*b1
から求めました。このとき A が 0 でなければ 答えが出る
はずですが、理論どおりにはいかなかったと思います。
そこで
プログラムは A が 0 ではなく A の 絶対値を 1/10^6 より
大きな値となるときとしました。

 以下に 私のプログラムを紹介します。
 蛇足かも知れません。そのときはお許しください。

[ 参考資料 ]
 以下のプログラムは 021inters.bat として保存すれば実行
できると思います。

@rem 交点(直線)
@echo off

REM #jww
REM #1ln 線(A)を指示してください。
REM #2ln 線(B)を指示してください。
REM #bz
REM #e

call:main jwc_temp.txt jwc_temp.bak
exit

:main
( echo bz
 gawk ^
'^
 BEGIN{ CONVFMT=OFMT=\"%%.15g\" }^
 END{ print \"pt\",inters^(ln[1],ln[2]^) }^
 /^^[ ]/ ^&^& NF==4 { lnn++; ln[lnn]=$0 }^
 function inters^(lni,lnj^){^
  $0=lni;^
  dx1=$3-$1;^
  dy1=$4-$2;^
  if^(dx1==0^){^
   a1=1;b1=0;c1=$1^
  } else {^
   a1=dy1/dx1;^
   b1=-1;^
   c1=a1*$1-$2^
  };^
  $0=lnj;^
  dx2=$3-$1;^
  dy2=$4-$2;^
  if^(dx2==0^){^
   a2=1;b2=0;c2=$1^
  } else {^
   a2=dy2/dx2;^
   b2=-1;^
   c2=a2*$1-$2^
  };^
  aa=a1*b2-a2*b1;^
  bc=b1*c2-b2*c1;^
  ca=c1*a2-c2*a1;^
  xerr=0;^
  if^(aa==0^){^
   if^(bc==0^) xerr=1^
  };^
  if^(aa==0^){^
   if^(bc!=0^){ if^(ca==0^) xerr=1 }^
  };^
  if^(sgn^(sqrt^(aa*aa^)-1/10^^6^)==-1^) xerr=1;^
  if^(xerr^){^
   exit err^(^)^
  } else {^
   return ^(c1*b2-c2*b1^)/aa FS ^(a1*c2-a2*c1^)/aa^
  }^
 }^
 function err^(^){ print \"he処理できません\" }^
 function sgn^(x^){ return x==0 ? x : ^( x==sqrt^(x*x^) ? 1 : -1 ^) }^
 ' %1
) > %2
del %1
ren %2 %1
goto:eof


Indexへ
(32115)←【32135】→(32140)
------------------------
【タイトル】Re(1):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32135 (32090)
【 日時 】08/11/28 22:14
【 発言者 】somem
【 リンク 】http://homepage2.nifty.com/cad_dwg/



▼hideさん:
>ユーザ定義関数function未実行の回避の仕方
>外部変形を作成してますが、下記ユーザ定義関数を使って交点計算を実行してみると、一方の線が鉛直線である時だけ、思わぬところへ点が書き出されます。
>

垂直線を含まない(x12!=x11 && x22!=x21)の条件では、
交点のX、Y座標が定義されていますが、
垂直線を含む他の2条件では、X座標、Y座標の条件が異なっています。
ここに、原因があるのではないでしょうか?
Awkスプリクトは、条件毎に入力データを1行づつ処理していきます。
ですから、(x11==x12 && x21!=x22)の場合、X座標は出力されますが、
Y座標は、その条件で何も出力されないか、0になる様な気がします。


Indexへ
(32135)←【32140】→(32141)
------------------------
【タイトル】Re(2):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32140 (32135)
【 日時 】08/11/29 03:11
【 発言者 】hide

たくさんの意見ありがとうございます。
とりあえず下記のようにプログラムを組みましたが、やはりバグが出ます。
垂線がある場合にバグが出るようなので、垂線を回避するため、三角形の各辺を伸縮したり、回転したりしてみましたが、バグが止まりません。ユーザ定義関数##回転系交点計算のIF文がうまく解決できればバグが取れると思っているのですが、、、、
私は、下記プログラムを見てのとおり、プログラムに関してはほとんど知識が無く、皆様の貴重な意見もよく理解できません。お手上げです。とりあえずは何とか使える程度にはできていますが、皆さん、試してみてください。改造等は自由にやってください。バグを取る方法もしくは取れたら書込みしていただければありがたいです。
 実験方法は、任意の点から、連続複線を利用してピラミッドのような1m置きの正三角形を書き、その線上に標高値を各面3点づつ書き込みます。そして、この外部変形を実行すると三角形の頂点にきれいな肛門マーク?ができ、標高値が書き込まなければいけません。垂線があり、ある何かの条件のもとでバグが発生することがあります。IF分に関しては、思ったように反応してくれませんので自身がありません。

              以下プログラム
            3面交線.BAT
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
@REM 【3面交線】A面3点、B面3点、C面3点の標高文字から路肩などの3面交線と標高を書出す。
@echo off
echo on
REM #jw
REM #cd
REM #hcA面3点、B面3点、C面3点の標高文字を選択(レイヤ不問)
REM #h0
REM #hc【線交点標高】
REM #g1
REM #1ch 標高文字A面(1)を指示してください(レイヤ不問)
REM #2ch 標高文字A面(2)を指示してください(レイヤ不問)
REM #3ch 標高文字A面(3)を指示してください(レイヤ不問)
REM #4ch 標高文字B面(1)を指示してください(レイヤ不問)
REM #5ch 標高文字B面(2)を指示してください(レイヤ不問)
REM #6ch 標高文字B面(3)を指示してください(レイヤ不問)
REM #7ch 標高文字C面(1)を指示してください(レイヤ不問)
REM #8ch 標高文字C面(2)を指示してください(レイヤ不問)
REM #9ch 標高文字C面(3)を指示してください(レイヤ不問)
REM #e

jgawk -f 3CROSS.awk jwc_temp.txt > temp.txt %1 %2 %3 %4 %5 %6 %7 %8 %9
:pause

del jwc_temp.txt
ren temp.txt jwc_temp.txt


Indexへ
(32140)←【32141】→(32142)
------------------------
【タイトル】Re(3):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32141 (32140)
【 日時 】08/11/29 03:16
【 発言者 】hide

3CROSS.AWK
..............................................................
# 【3CROSS】A面3点、B面3点、C面3点の標高文字から路肩などの交線と標高を書き出す。


         #A面標高値のXYZ座標取得

     (/^hhp1ch/){
           getline
            A01X=$2*1;
            A01Y=$3*1;
            A01Z=substr($6,2)*1000;
           }
     (/^hhp2ch/){
           getline
            A02X=$2*1;
            A02Y=$3*1;
            A02Z=substr($6,2)*1000;
           }
     (/^hhp3ch/){
           getline
            A03X=$2*1;
            A03Y=$3*1;
            A03Z=substr($6,2)*1000;
           }
         #B面標高値のXYZ座標取得
     (/^hhp4ch/){
           getline
            B01X=$2*1;
            B01Y=$3*1;
            B01Z=substr($6,2)*1000;
           }
     (/^hhp5ch/){
           getline
            B02X=$2*1;
            B02Y=$3*1;
            B02Z=substr($6,2)*1000;
           }
     (/^hhp6ch/){
           getline
            B03X=$2*1;
            B03Y=$3*1;
            B03Z=substr($6,2)*1000;
           }
         #C面標高値のXYZ座標取得
     (/^hhp7ch/){
           getline
            C01X=$2*1;
            C01Y=$3*1;
            C01Z=substr($6,2)*1000;
           }
     (/^hhp8ch/){
           getline
            C02X=$2*1;
            C02Y=$3*1;
            C02Z=substr($6,2)*1000;
           }
     (/^hhp9ch/){
           getline
            C03X=$2*1;
            C03Y=$3*1;
            C03Z=substr($6,2)*1000;
          ##X−Y平面
           #X−Y平面上の各辺の角度

SR0=100
A1X=expansionx(A01X,A01Y,A02X,A02Y,SR0)
A1Y=expansiony(A01X,A01Y,A02X,A02Y,SR0)
A1Z=expansionz(A01X,A01Y,A01Z,A02X,A02Y,A02Z,A1X,A1Y)
SR1=110
B1X=expansionx(B01X,B01Y,B02X,B02Y,SR1)
B1Y=expansiony(B01X,B01Y,B02X,B02Y,SR1)
B1Z=expansionz(B01X,B01Y,B01Z,B02X,B02Y,B02Z,B1X,B1Y)
SR2=120
C1X=expansionx(C01X,C01Y,C02X,C02Y,SR2)
C1Y=expansiony(C01X,C01Y,C02X,C02Y,SR2)
C1Z=expansionz(C01X,C01Y,C01Z,C02X,C02Y,C02Z,C1X,C1Y)
SR3=130
A2X=expansionx(A02X,A02Y,A03X,A03Y,SR3)
A2Y=expansiony(A02X,A02Y,A03X,A03Y,SR3)
A2Z=expansionz(A02X,A02Y,A02Z,A03X,A03Y,A03Z,A2X,A2Y)
SR4=140
B2X=expansionx(B02X,B02Y,B03X,B03Y,SR4)
B2Y=expansiony(B02X,B02Y,B03X,B03Y,SR4)
B2Z=expansionz(B02X,B02Y,B02Z,B03X,B03Y,B03Z,B2X,B2Y)
SR5=150
C2X=expansionx(C02X,C02Y,C03X,C03Y,SR5)
C2Y=expansiony(C02X,C02Y,C03X,C03Y,SR5)
C2Z=expansionz(C02X,C02Y,C02Z,C03X,C03Y,C03Z,C2X,C2Y)
SR6=160
A3X=expansionx(A03X,A03Y,A01X,A01Y,SR6)
A3Y=expansiony(A03X,A03Y,A01X,A01Y,SR6)
A3Z=expansionz(A03X,A03Y,A03Z,A01X,A01Y,A01Z,A3X,A3Y)
SR7=170
B3X=expansionx(B03X,B03Y,B01X,B01Y,SR7)
B3Y=expansiony(B03X,B03Y,B01X,B01Y,SR7)
B3Z=expansionz(B03X,B03Y,B03Z,B01X,B01Y,B01Z,B3X,B3Y)
SR8=180
C3X=expansionx(C03X,C03Y,C01X,C01Y,SR8)
C3Y=expansiony(C03X,C03Y,C01X,C01Y,SR8)
C3Z=expansionz(C03X,C03Y,C03Z,C01X,C01Y,C01Z,C3X,C3Y)


A12a=atan2((A1Y-A2Y),(A1X-A2X));
B12a=atan2((B1Y-B2Y),(B1X-B2X));
C12a=atan2((C1Y-C2Y),(C1X-C2X));
A23a=atan2((A2Y-A3Y),(A2X-A3X));
B23a=atan2((B2Y-B3Y),(B2X-B3X));
C23a=atan2((C2Y-C3Y),(C2X-C3X));
A31a=atan2((A3Y-A1Y),(A3X-A1X));
B31a=atan2((B3Y-B1Y),(B3X-B1X));
C31a=atan2((C3Y-C1Y),(C3X-C1X));


           #X−Y平面上の各辺長

A12L=(A1X-A2X)/cos(A12a);
B12L=(B1X-B2X)/cos(B12a);
C12L=(C1X-C2X)/cos(C12a);
A23L=(A2X-A3X)/cos(A23a);
B23L=(B2X-B3X)/cos(B23a);
C23L=(C2X-C3X)/cos(C23a);
A31L=(A3X-A1X)/cos(A31a);
B31L=(B3X-B1X)/cos(B31a);
C31L=(C3X-C1X)/cos(C31a);


           #XY−Z断面上の各辺の傾き
ZA12M=(A1Z-A2Z)/A12L
ZB12M=(B1Z-B2Z)/B12L
ZC12M=(C1Z-C2Z)/C12L
ZA23M=(A2Z-A3Z)/A23L
ZB23M=(B2Z-B3Z)/B23L
ZC23M=(C2Z-C3Z)/C23L
ZA31M=(A3Z-A1Z)/A31L
ZB31M=(B3Z-B1Z)/B31L
ZC31M=(C3Z-C1Z)/C31L


AB1X=koutenx(A1X,A1Y,A2X,A2Y,B3X,B3Y,B1X,B1Y);
AB1Y=kouteny(A1X,A1Y,A2X,A2Y,B3X,B3Y,B1X,B1Y);
AB2X=koutenx(A1X,A1Y,A2X,A2Y,B1X,B1Y,B2X,B2Y);
AB2Y=kouteny(A1X,A1Y,A2X,A2Y,B1X,B1Y,B2X,B2Y);
AB1Z=B3Z+ZB31M*(AB1X-B3X)/cos(B31a);
AB2Z=B1Z+ZB12M*(AB2X-B1X)/cos(B12a);
AB121L=A1X/cos(A12a);
AB122L=A2X/cos(A12a);
AB1L=AB1X/cos(A12a);
AB2L=AB2X/cos(A12a);
AB10X=koutenx(A2X,A2Y,A3X,A3Y,B3X,B3Y,B1X,B1Y);
AB10Y=kouteny(A2X,A2Y,A3X,A3Y,B3X,B3Y,B1X,B1Y);
AB20X=koutenx(A2X,A2Y,A3X,A3Y,B1X,B1Y,B2X,B2Y);
AB20Y=kouteny(A2X,A2Y,A3X,A3Y,B1X,B1Y,B2X,B2Y);
AB10Z=B3Z+ZB31M*(AB10X-B3X)/cos(B31a);
AB20Z=B1Z+ZB12M*(AB20X-B1X)/cos(B12a);
AB232L=A2X/cos(A23a);
AB233L=A3X/cos(A23a);
AB10L=AB10X/cos(A23a);
AB20L=AB20X/cos(A23a);
BC1X=koutenx(B1X,B1Y,B2X,B2Y,C3X,C3Y,C1X,C1Y);
BC1Y=kouteny(B1X,B1Y,B2X,B2Y,C3X,C3Y,C1X,C1Y);
BC2X=koutenx(B1X,B1Y,B2X,B2Y,C1X,C1Y,C2X,C2Y);
BC2Y=kouteny(B1X,B1Y,B2X,B2Y,C1X,C1Y,C2X,C2Y);
BC1Z=C3Z+ZC31M*(BC1X-C3X)/cos(C31a);
BC2Z=C1Z+ZC12M*(BC2X-C1X)/cos(C12a);
BC121L=B1X/cos(B12a);
BC122L=B2X/cos(B12a);
BC1L=BC1X/cos(B12a);
BC2L=BC2X/cos(B12a);
BC10X=koutenx(B2X,B2Y,B3X,B3Y,C3X,C3Y,C1X,C1Y);
BC10Y=kouteny(B2X,B2Y,B3X,B3Y,C3X,C3Y,C1X,C1Y);
BC20X=koutenx(B2X,B2Y,B3X,B3Y,C1X,C1Y,C2X,C2Y);
BC20Y=kouteny(B2X,B2Y,B3X,B3Y,C1X,C1Y,C2X,C2Y);
BC10Z=C3Z+ZC31M*(BC10X-C3X)/cos(C31a);
BC20Z=C1Z+ZC12M*(BC20X-C1X)/cos(C12a);
BC232L=B2X/cos(B23a);
BC233L=B3X/cos(B23a);
BC10L=BC10X/cos(B23a);
BC20L=BC20X/cos(B23a);
CA1X=koutenx(C1X,C1Y,C2X,C2Y,A3X,A3Y,A1X,A1Y);
CA1Y=kouteny(C1X,C1Y,C2X,C2Y,A3X,A3Y,A1X,A1Y);
CA2X=koutenx(C1X,C1Y,C2X,C2Y,A1X,A1Y,A2X,A2Y);
CA2Y=kouteny(C1X,C1Y,C2X,C2Y,A1X,A1Y,A2X,A2Y);
CA1Z=A3Z+ZA31M*(CA1X-A3X)/cos(A31a);
CA2Z=A1Z+ZA12M*(CA2X-A1X)/cos(A12a);
CA121L=C1X/cos(C12a);
CA122L=C2X/cos(C12a);
CA1L=CA1X/cos(C12a);
CA2L=CA2X/cos(C12a);
CA10X=koutenx(C2X,C2Y,C3X,C3Y,A3X,A3Y,A1X,A1Y);
CA10Y=kouteny(C2X,C2Y,C3X,C3Y,A3X,A3Y,A1X,A1Y);
CA20X=koutenx(C2X,C2Y,C3X,C3Y,A1X,A1Y,A2X,A2Y);
CA20Y=kouteny(C2X,C2Y,C3X,C3Y,A1X,A1Y,A2X,A2Y);
CA10Z=A3Z+ZA31M*(CA10X-A3X)/cos(A31a);
CA20Z=A1Z+ZA12M*(CA20X-A1X)/cos(A12a);
CA232L=C2X/cos(C23a);
CA233L=C3X/cos(C23a);
CA10L=CA10X/cos(C23a);
CA20L=CA20X/cos(C23a);

AB1L=koutenx(AB121L,A1Z,AB122L,A2Z,AB1L,AB1Z,AB2L,AB2Z);
AB2L=koutenx(AB232L,A2Z,AB233L,A3Z,AB10L,AB10Z,AB20L,AB20Z);
BC1L=koutenx(BC121L,B1Z,BC122L,B2Z,BC1L,BC1Z,BC2L,BC2Z);
BC2L=koutenx(BC232L,B2Z,BC233L,B3Z,BC10L,BC10Z,BC20L,BC20Z);
CA1L=koutenx(CA121L,C1Z,CA122L,C2Z,CA1L,CA1Z,CA2L,CA2Z);
CA2L=koutenx(CA232L,C2Z,CA233L,C3Z,CA10L,CA10Z,CA20L,CA20Z);

AAB1X=A1X+(AB1L-AB121L)*cos(A12a);
AAB2X=A2X+(AB2L-AB232L)*cos(A23a);
BBC1X=B1X+(BC1L-BC121L)*cos(B12a);
BBC2X=B2X+(BC2L-BC232L)*cos(B23a);
CCA1X=C1X+(CA1L-CA121L)*cos(C12a);
CCA2X=C2X+(CA2L-CA232L)*cos(C23a);

AAB1Y=A1Y+(AB1L-AB121L)*sin(A12a);
AAB2Y=A2Y+(AB2L-AB232L)*sin(A23a);
BBC1Y=B1Y+(BC1L-BC121L)*sin(B12a);
BBC2Y=B2Y+(BC2L-BC232L)*sin(B23a);
CCA1Y=C1Y+(CA1L-CA121L)*sin(C12a);
CCA2Y=C2Y+(CA2L-CA232L)*sin(C23a);

PAX=koutenx(AAB1X,AAB1Y,AAB2X,AAB2Y,BBC1X,BBC1Y,BBC2X,BBC2Y);
PBX=koutenx(BBC1X,BBC1Y,BBC2X,BBC2Y,CCA1X,CCA1Y,CCA2X,CCA2Y);
PCX=koutenx(CCA1X,CCA1Y,CCA2X,CCA2Y,AAB1X,AAB1Y,AAB2X,AAB2Y);

PAY=kouteny(AAB1X,AAB1Y,AAB2X,AAB2Y,BBC1X,BBC1Y,BBC2X,BBC2Y);
PBY=kouteny(BBC1X,BBC1Y,BBC2X,BBC2Y,CCA1X,CCA1Y,CCA2X,CCA2Y);
PCY=kouteny(CCA1X,CCA1Y,CCA2X,CCA2Y,AAB1X,AAB1Y,AAB2X,AAB2Y);

Aa=atan2((AAB1Y-AAB2Y),(AAB1X-AAB2X));
Ba=atan2((BBC1Y-BBC2Y),(BBC1X-BBC2X));
Ca=atan2((CCA1Y-CCA2Y),(CCA1X-CCA2X));

#if(PAX==PBX&&PBX==PCX){PX=PAX}
#else
#   if(PAX==PBX&&PBX!=PCX){PX=PAX}
#   else
#     if(PBX==PCX&&PCX!=PAX){PX=PBX}
#     else
#        if(PCX==PAX&&PAX!=PBX){PX=PCX}
#       
#     
#  
#
#if(PAY==PBY&&PBY==PCY){PY=PAY}
#else
#if(PAY==PBY&&PBY!=PCY){PY=PAY}
#   else
#     if(PBY==PCY&&PCY!=PAY){PY=PBY}
#     else
#        if(PCY==PAY&&PAY!=PBY){PY=PCY}


Indexへ
(32141)←【32142】→(32152)
------------------------
【タイトル】Re(4):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32142 (32141)
【 日時 】08/11/29 03:19
【 発言者 】hide

▼hideさん:
>3CROSS.AWKの続き
>..............................................................
         #求点からN(m)離れた方向点の算出

  N=1000        # 数値変更により、線長を変更できる。

      PA1X=PAX-N*cos(Aa);   PA1Y=PAY-N*sin(Aa);
      PB1X=PBX-N*cos(Ba);   PB1Y=PBY-N*sin(Ba);
      PC1X=PCX-N*cos(Ca);   PC1Y=PCY-N*sin(Ca);

      PA2X=PAX+N*cos(Aa);   PA2Y=PAY+N*sin(Aa);
      PB2X=PBX+N*cos(Ba);   PB2Y=PBY+N*sin(Ba);
      PC2X=PCX+N*cos(Ca);   PC2Y=PCY+N*sin(Ca);

         #求点標高の算出

APPX=koutenx(A1X,A1Y,A2X,A2Y,A3X,A3Y,PAX,PAY)
APPY=kouteny(A1X,A1Y,A2X,A2Y,A3X,A3Y,PAX,PAY)
BPPX=koutenx(B1X,B1Y,B2X,B2Y,B3X,B3Y,PBX,PBY)
BPPY=kouteny(B1X,B1Y,B2X,B2Y,B3X,B3Y,PBX,PBY)
CPPX=koutenx(C1X,C1Y,C2X,C2Y,C3X,C3Y,PCX,PCY)
CPPY=kouteny(C1X,C1Y,C2X,C2Y,C3X,C3Y,PCX,PCY)
AA1L=A1Y/sin(A12a)
APPL=APPY/sin(A12a)
AA2L=A2Y/sin(A12a)
APPZ=onliney(AA1L,A1Z,AA2L,A2Z,APPL)
APPa=atan2((PAY-A3Y),(PAX-A3X))
APPLL=APPY/sin(APPa)
AA3L=A3Y/sin(APPa)
APL=PAY/sin(APPa)
PAZ=onliney(APPLL,APPZ,AA3L,A3Z,APL)
#PAZ=fix(PAZ,3)

BB1L=B1Y/sin(B12a)
BPPL=BPPY/sin(B12a)
BB2L=B2Y/sin(B12a)
BPPZ=onliney(BB1L,B1Z,BB2L,B2Z,BPPL)
BPPa=atan2((PBY-B3Y),(PBX-B3X))
BPPLL=BPPY/sin(BPPa)
BB3L=B3Y/sin(BPPa)
BPL=PAY/sin(BPPa)
PBZ=onliney(BPPLL,BPPZ,BB3L,B3Z,BPL)
#PBZ=fix(PBZ,3)

CC1L=C1Y/sin(C12a)
CPPL=CPPY/sin(C12a)
CC2L=C2Y/sin(C12a)
CPPZ=onliney(CC1L,C1Z,CC2L,C2Z,CPPL)
CPPa=atan2((PCY-C3Y),(PCX-C3X))
CPPLL=CPPY/sin(CPPa)
CC3L=C3Y/sin(CPPa)
CPL=PAY/sin(CPPa)
PCZ=onliney(CPPLL,CPPZ,CC3L,C3Z,CPL)
#PCZ=fix(PCZ,3)

#if(PAZ==PBZ&&PBZ==PCZ){PZ=PAZ}
#else
#   if(PAZ==PBZ&&PBZ!=PCZ){PZ=PAZ}
#   else
#     if(PBZ==PCZ&&PCZ!=PAZ){PZ=PBZ}
#     else
#        if(PCZ==PAZ&&PAZ!=PBZ){PZ=PCZ}


     }

          #XYZの転送

  END{
    {
       printf" %e %e %e %e\n",PA1X,PA1Y,PA2X,PA2Y;
       printf" %e %e %e %e\n",PB1X,PB1Y,PB2X,PB2Y;
       printf" %e %e %e %e\n",PC1X,PC1Y,PC2X,PC2Y;
    printf("ch %e %e %e %e \"FH=%1.3f\n",PAX,PAY,1,0,PAZ/1000)

##if(PAZ==PBZ&&PBZ==PCZ){
##    printf("ch %e %e %e %e \"FH=%1.3f\n",PAX,PAY,1,0,PAZ/1000)
##           }
###else
##   if(PAZ==PBZ){
#          printf("ch %e %e %e %e \"FHA=%1.3f\n",PAX,PAY,1,0,PAZ/1000)
##         }
###    else
##    if(PBZ==PCZ){
#          printf("ch %e %e %e %e \"FHB=%1.3f\n",PBX,PBY,1,0,PBZ/1000)
##          }
###       else
##         if(PCZ==PAZ){
#           printf("ch %e %e %e %e \"FHC=%1.3f\n",PCX,PCY,1,0,PCZ/1000)
##                }


#printf"pt %e %e\n",PAX,PAY;
#printf"pt %e %e\n",PBX,PBY;
#printf"pt %e %e\n",PCX,PCY;
    }
   }


##ユーザー定義関数
#線上座標 Y=
function onliney(x1,y1,x2,y2,x3){
if(y2==y1){
return y1;
      }
if(x2!=x1&&y2!=y1){
m=(y2-y1)/(x2-x1);
return y1+m*(x3-x1);
             }
                 }


#線上伸縮点座標 X=
function expansionx(x1,y1,x2,y2,l3){
if(x2==x1){
return x2
y=y2+l3
      }
if(y2==y1){
return x2+l3
y=y2
      }
a=atan2((y1-y2),(x1-x2));
return x2+l3*cos(a)
y=y2+l3*sin(a)
                  }

#線上伸縮点座標 Y=
function expansiony(x1,y1,x2,y2,l3){
if(x2==x1){
x=x2
return y2+l3
      }
if(y2==y1){
x=x2+l3
return y2
      }
a=atan2((y1-y2),(x1-x2));
x=x2+l3*cos(a)
return y2+l3*sin(a)
                  }

#線上伸縮点座標 Z=
function expansionz(x1,y1,z1,x2,y2,z2,x3,y3){
if(x2==x1){
l1=y1
l2=y2
l3=y3
m=(z2-z1)/(l2-l1);
return z1+m*(l3-l1);
      }

a=atan2((y1-y2),(x1-x2));
l1=x1/cos(a);
l2=x2/cos(a);
l3=x3/cos(a);
m=(z2-z1)/(l2-l1);
return z1+m*(l3-l1);
                      }

#2線4点交点座標 X=
function koutenx(x11,y11,x12,y12,x21,y21,x22,y22){
dx1=x12-x11;dy1=y12-y11
dx2=x22-x21;dy2=y22-y21
if(dx1==0&&dx2==0){print"h#平行線です";exit}
if(dx1==0){
      a2=dy2/dx2
#      if ( a2*a2 > 360 ) { print "h# ほぼ平行線です"; exit } #3度以内
      b2=y21+y22-a2*(x21+x22)
       x=x12
       y=a2*x+b2/2
return x

      }else
         if(dx2==0){
              a1=dy1/dx1
#              if ( a1*a1 > 360 ) { print "h# ほぼ平行線です"; exit }
              b1=y11+y12-a1*(x11+x12)
               x=x22
               y=a1*x+b1/2
return x
               }
else{
                  a1=dy1/dx1
                  a2=dy2/dx2
                 a12=a1-a2
                if(a12==0){print"h#平行線です";exit}
#      if (a12*a12 < 0.003) { print "h# ほぼ平行線です"; exit }
b1=y11+y12-a1*(x11+x12)
b2=y21+y22-a2*(x21+x22)
x=((b2-b1)/2)/a12
y=a1*x+b1/2
return x
                  }
                          }
#2線4点交点座標 Y=
function kouteny(x11,y11,x12,y12,x21,y21,x22,y22){
#交点を求める
dx1=x12-x11;dy1=y12-y11
dx2=x22-x21;dy2=y22-y21
if(dx1==0&&dx2==0){print"h#平行線です";exit}
if(dx1==0){
      a2=dy2/dx2
#      if ( a2*a2 > 360 ) { print "h# ほぼ平行線です"; exit } #3度以内
      b2=y21+y22-a2*(x21+x22)
      x=x12
      y=a2*x+b2/2
return y
      }else
         if(dx2==0){
              a1=dy1/dx1
#              if ( a1*a1 > 360 ) { print "h# ほぼ平行線です"; exit }
              b1=y11+y12-a1*(x11+x12)
               x=x22
               y=a1*x+b1/2
return y
              }else{
                 a1=dy1/dx1
                 a2=dy2/dx2
                 a12=a1-a2
               if(a12==0){print"h#平行線です";exit}
#             if (a12*a12 < 0.003) { print "h# ほぼ平行線です"; exit }
                 b1=y11+y12-a1*(x11+x12)
                 b2=y21+y22-a2*(x21+x22)
                  x=((b2-b1)/2)/a12
                  y=a1*x+b1/2
return y
                  }
                          }

##回転系交点計算 X=
function rkoutenx(x11,y11,x12,y12,x21,y21,x22,y22){
           #絶対角の算出
pi=atan2(0,-1)
a11=atan2(y11,x11)
a12=atan2(y12,x12);
a21=atan2(y21,x21);
a22=atan2(y22,x22)
a=(a11+a12+a21+a22)/4000 #回転角の決定
aa11=a11+a;
if(aa11<-pi){aa11=aa11+pi}else{if(aa11>=pi){aa11=aa11-pi}}
aa12=a12+a;
if(aa12<-pi){aa12=aa12+pi}else{if(aa12>=pi){aa12=aa12-pi}}
aa21=a21+a;
if(aa21<-pi){aa21=aa21+pi}else{if(aa21>=pi){aa21=aa21-pi}}
aa22=a22+a;
if(aa22<-pi){aa22=aa22+pi}else{if(aa22>=pi){aa22=aa22-pi}}
            #回転相対座標算出
xx11=sqrt(x11^2+y11^2)*cos(aa11);yy11=sqrt(x11^2+y11^2)*sin(aa11);
xx12=sqrt(x12^2+y12^2)*cos(aa12);yy12=sqrt(x12^2+y12^2)*sin(aa12);
xx21=sqrt(x21^2+y21^2)*cos(aa21);yy21=sqrt(x21^2+y21^2)*sin(aa21);
xx22=sqrt(x22^2+y22^2)*cos(aa22);yy22=sqrt(x22^2+y22^2)*sin(aa22);
            #相対座標交点計算
m1=(yy12-yy11)/(xx12-xx11);
m2=(yy22-yy21)/(xx22-xx21);
xx=(yy21-yy11+m1*xx11-m2*xx21)/(m1-m2);
yy=yy11+m1*(xx-xx11);
            #回転絶対座標算出
ra=atan2(yy,xx)
if(((ra-a)>-pi)&&((ra-a)<=pi)){rea=(ra-a)}
else{if((ra-a)<-pi){rea=(ra-a)+pi}else{if((ra-a)>=pi){rea=(ra-a)-pi}}}
x=sqrt(xx^2+yy^2)*cos(rea);
y=sqrt(xx^2+yy^2)*sin(rea)

return x
                   }
##回転系交点計算 Y=
function rkouteny(x11,y11,x12,y12,x21,y21,x22,y22){
           #絶対角の算出
pi=atan2(0,-1)
a11=atan2(y11,x11)
a12=atan2(y12,x12);
a21=atan2(y21,x21);
a22=atan2(y22,x22)
a=(a11+a12+a21+a22)/4 #回転角の決定
aa11=a11+a;
if((aa11>-pi)&&(aa11<=pi)){aa11}
else{if(aa11<-pi){aa11=aa11+pi}else{if(aa11>=pi){aa11=aa11-pi}}}
aa12=a12+a;
if((aa12>-pi)&&(aa12<=pi)){aa12}
else{if(aa12<-pi){aa12=aa12+pi}else{if(aa12>=pi){aa12=aa12-pi}}}
aa21=a21+a;
if((aa21>-pi)&&(aa21<=pi)){aa21}
else{if(aa21<-pi){aa21=aa21+pi}else{if(aa21>=pi){aa21=aa21-pi}}}
aa22=a22+a;
if((aa22>-pi)&&(aa22<=pi)){aa22}
else{if(aa22<-pi){aa22=aa22+pi}else{if(aa22>=pi){aa22=aa22-pi}}}
            #回転相対座標算出
xx11=sqrt(x11^2+y11^2)*cos(aa11);yy11=sqrt(x11^2+y11^2)*sin(aa11);
xx12=sqrt(x12^2+y12^2)*cos(aa12);yy12=sqrt(x12^2+y12^2)*sin(aa12);
xx21=sqrt(x21^2+y21^2)*cos(aa21);yy21=sqrt(x21^2+y21^2)*sin(aa21);
xx22=sqrt(x22^2+y22^2)*cos(aa22);yy22=sqrt(x22^2+y22^2)*sin(aa22);
            #相対座標交点計算
m1=(yy12-yy11)/(xx12-xx11);
m2=(yy22-yy21)/(xx22-xx21);
xx=(yy21-yy11+m1*xx11-m2*xx21)/(m1-m2);
yy=yy11+m1*(xx-xx11);
            #回転絶対座標算出
ra=atan2(yy,xx)
if(((ra-a)>-pi)&&((ra-a)<=pi)){rea=(ra-a)}
else{if((ra-a)<-pi){rea=(ra-a)+pi}else{if((ra-a)>=pi){rea=(ra-a)-pi}}}
x=sqrt(xx^2+yy^2)*cos(rea);
y=sqrt(xx^2+yy^2)*sin(rea)

return y
                   }
#四捨五入
function fix(x,n){
return int((x/10^n)+0.5)*10^n;
         }
。。。。。。。。。。。。。。。終わり


Indexへ
(32142)←【32152】→(32153)
------------------------
【タイトル】Re(3):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32152 (32140)
【 日時 】08/11/29 19:10
【 発言者 】Kazuo Miyake qqza3hq89@aioros.ocn.ne.jp

▼hideさん:
>たくさんの意見ありがとうございます。
>とりあえず下記のようにプログラムを組みましたが、やはりバグが出ます。
>垂線がある場合にバグが出るようなので、垂線を回避するため、三角形の各辺を伸縮したり、回転したりしてみましたが、バグが止まりません。ユーザ定義関数##回転系交点計算のIF文がうまく解決できればバグが取れると思っているのですが、、、、
>私は、下記プログラムを見てのとおり、プログラムに関してはほとんど知識が無く、皆様の貴重な意見もよく理解できません。お手上げです。とりあえずは何とか使える程度にはできていますが、皆さん、試してみてください。改造等は自由にやってください。バグを取る方法もしくは取れたら書込みしていただければありがたいです。
> 実験方法は、任意の点から、連続複線を利用してピラミッドのような1m置きの正三角形を書き、その線上に標高値を各面3点づつ書き込みます。そして、この外部変形を実行すると三角形の頂点にきれいな肛門マーク?ができ、標高値が書き込まなければいけません。垂線があり、ある何かの条件のもとでバグが発生することがあります。IF分に関しては、思ったように反応してくれませんので自身がありません。
>
>              以下プログラム
>            3面交線.BAT
>。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
>@REM 【3面交線】A面3点、B面3点、C面3点の標高文字から路肩などの3面交線と標高を書出す。
>@echo off
>echo on
>REM #jw
>REM #cd
>REM #hcA面3点、B面3点、C面3点の標高文字を選択(レイヤ不問)
>REM #h0
>REM #hc【線交点標高】
>REM #g1
>REM #1ch 標高文字A面(1)を指示してください(レイヤ不問)
>REM #2ch 標高文字A面(2)を指示してください(レイヤ不問)
>REM #3ch 標高文字A面(3)を指示してください(レイヤ不問)
>REM #4ch 標高文字B面(1)を指示してください(レイヤ不問)
>REM #5ch 標高文字B面(2)を指示してください(レイヤ不問)
>REM #6ch 標高文字B面(3)を指示してください(レイヤ不問)
>REM #7ch 標高文字C面(1)を指示してください(レイヤ不問)
>REM #8ch 標高文字C面(2)を指示してください(レイヤ不問)
>REM #9ch 標高文字C面(3)を指示してください(レイヤ不問)
>REM #e
>
>jgawk -f 3CROSS.awk jwc_temp.txt > temp.txt %1 %2 %3 %4 %5 %6 %7 %8 %9
>:pause
>
>del jwc_temp.txt
>ren temp.txt jwc_temp.txt

 処理内容は かなり専門性が高いようで 当方は理解できないので
すが 2直線の交点を算定するルーチンは つぎのような処理をすれ
ば 垂線 が存在しても 問題はなくなると思います。

 たいへんでしょうが
 プログラムが無事に完成することをお祈りします。

[ バッチファイル ]
00000inters.bat

@rem 交点(直線)
@echo off

REM #jw
REM #1ln 線(A)を指示してください。
REM #2ln 線(B)を指示してください。
REM #bz
REM #cd
REM #e

gawk -f 00000inters.awk jwc_temp.txt > temp.txt
del jwc_temp.txt
ren temp.txt jwc_temp.txt
exit


[ プログラムファイル ]
00000inters.awk

BEGIN {
 #FS = " " #ファイルセパレーター
 CONVFMT = OFMT = "%.15g"
 n = 1
}

 /^[ ]/ && NF == 4 && n == 1 { ln1 = $0; n++; next }
 /^[ ]/ && NF == 4 && n == 2 { ln2 = $0; n++; next }

END {
 $0 = ln1 FS ln2
 $0 = kouten($1,$2,$3,$4,$5,$6,$7,$8)
 x = $1
 y = $2
 print "pt",x,y #2直線の交点に点を打つ
}

#2線4点交点座標 X FS Y
#
#2線を
# a1*x+b1*y+c1 = 0
# a2*x+b2*y+c2 = 0
#に変換して
# aa = a1*b2-a2*b1
#が ゼロ でなければ
# x = (c1*b2-c2*b1)/aa
# y = (a1*c2-a2*c1)/aa
#から 交点の座標値 が得られます
#
function kouten(x11,y11,x12,y12,x21,y21,x22,y22){
dx1=x12-x11;dy1=y12-y11
dx2=x22-x21;dy2=y22-y21
 if( dx1 == 0 ){
  a1 = 1
  b1 = 0
  c1 = x11
 } else {
  a1 = dy1/dx1
  b1 = -1
  c1 = a1*x11-y11
 }
 if( dx2 == 0 ){
  a2 = 1
  b2 = 0
  c2 = x21
 } else {
  a2 = dy2/dx2
  b2 = -1
  c2 = a2*x21-y21
 }
 aa = a1*b2-a2*b1
 bc = b1*c2-b2*c1
 ca = c1*a2-c2*a1
 if( aa != 0 ){
  x = (c1*b2-c2*b1)/aa
  y = (a1*c2-a2*c1)/aa
 } else {
  if( bc == 0 && ca != 0 ){ print"h#平行線です" }
  if( bc != 0 && ca == 0 ){ print"h#平行線です" }
  if( bc == 0 && ca == 0 ){ print"h#重なっているか、同じ直線上にあります" }
  exit
 }
 return x FS y
}


Indexへ
(32152)←【32153】→(32155)
------------------------
【タイトル】Re(3):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32153 (32140)
【 日時 】08/11/29 21:33
【 発言者 】KITI

hideさん こんばんは、KITIです。

再び具体策でないので 恐縮ですが・・

>##回転系交点計算のIF文がうまく解決できれば・・

おそらく計算誤差が原因だと思います。
KITIは if(x1 == x2) を if(sqrt((x1-x2)^2) < 0.00001)
なんて やってました。精度は落ちますが・・。

交点を求めるのに回転をするのも一つの方法ではありますが
回転のたびに 計算誤差が生じます。

手元の参考書によると 線A(x1,y1--x2,y2) と 線B(x3,y3--x4,y4)
の交点 X,Yは

X = -1/k{(y2-y1)(x4-x3)x1-(y4-y3)(x2-x1)x3+(y3-y1)(x2-x1)(x4-x3)}
Y = 1/k{(x2-x1)(y4-y3)y1-(x4-x3)(y2-y1)y3+(x3-x1)(y2-y1)(y4-y3)}
ただし k = (x2-x1)(y4-y3)-(x4-x3)(y2-y1)

だそうです。ただし線Aと線Bが平行の場合 kが0となるのであらかじめ
continueする必要があります。


#四捨五入
function fix(x,n){
return int((x/10^n)+0.5)*10^n;
         }
は return int((x*10^n)+0.5)/10^n の 転写間違えですネ 


最後に よけいな一言・・・・
検証は出来るだけ簡単な図形で 再現できるデータをコピーして
変数の値を追いかけると 問題点を見つけやすいと思います。
頑張ってください!!

  デワデワ   広島のKITIより


Indexへ
(32153)←【32155】//(32091)
------------------------
【タイトル】Re(4):外部変形awkプログラムでの座標回転移動と鉛直線のある交点計算
【記事番号】 32155 (32153)
【 日時 】08/11/30 02:10
【 発言者 】hide

▼KITIさん:
>hideさん こんばんは、KITIです。
>
>再び具体策でないので 恐縮ですが・・
>
>>##回転系交点計算のIF文がうまく解決できれば・・
>
>おそらく計算誤差が原因だと思います。
>KITIは if(x1 == x2) を if(sqrt((x1-x2)^2) < 0.00001)
>なんて やってました。精度は落ちますが・・。
>
>交点を求めるのに回転をするのも一つの方法ではありますが
>回転のたびに 計算誤差が生じます。
>
>手元の参考書によると 線A(x1,y1--x2,y2) と 線B(x3,y3--x4,y4)
>の交点 X,Yは
>
>X = -1/k{(y2-y1)(x4-x3)x1-(y4-y3)(x2-x1)x3+(y3-y1)(x2-x1)(x4-x3)}
>Y = 1/k{(x2-x1)(y4-y3)y1-(x4-x3)(y2-y1)y3+(x3-x1)(y2-y1)(y4-y3)}
>ただし k = (x2-x1)(y4-y3)-(x4-x3)(y2-y1)
>
>だそうです。ただし線Aと線Bが平行の場合 kが0となるのであらかじめ
>continueする必要があります。
>
>
>#四捨五入
>function fix(x,n){
>return int((x/10^n)+0.5)*10^n;
>         }
>は return int((x*10^n)+0.5)/10^n の 転写間違えですネ 
>
>
>最後に よけいな一言・・・・
>検証は出来るだけ簡単な図形で 再現できるデータをコピーして
>変数の値を追いかけると 問題点を見つけやすいと思います。
>頑張ってください!!
>
>  デワデワ   広島のKITIより
プログラム完成しました。
皆さんの言われるように、
a1*x+b1*y+c1 = 0
a2*x+b2*y+c2 = 0
の線形代数とかいうものも試してみましたが、単独ではうまくいってもスクリプトに組み込むと結果はうまくいかないようでした。
結局、220行目あたりを回転して交点処理をを行うことでバグら無くなりました。
if文の中で、2*piを加減しなければならないところをpiにしていました。
kitiさんのおっしゃるとおり、このスクリプトは、何度も多重計算してるので数値に小さな誤差が発生し、0になるところが大変小さな小数値となって、if文を潜り抜けたのでしょうか?
 余計な一言...は、もっといっぱいいただけると大変ありがたいです。大変参考になります。
if文に四苦八苦し、fix文のところでもすごく苦労しました。
貴重な意見、御時間を頂き、大変ありがとうございました。