jw_cad 外部変形 - (564) なでしこで楕円弧の長さ(表示画面のスケール)を計測表示する -

外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。

 

なでしこで楕円弧の長さを計算する

/* なでしこで楕円弧の長さ(表示画面のスケール)を計測表示する
@cls & echo off
path C:\nadesiko_1_589;%path%
copy jwc_temp.txt myfiles > nul
cnako %0 > jwc_temp.txt
goto:eof

REM #jww
REM #1ci 長さを計測する円・円弧を指示してください。
REM #e
*/

●SPLIT(s)
  sを「 」で区切ったものを戻す
●CHOP(s)
  sを空白除去して戻す
●ARC_L(k, p1, p2)
  Ekとは実数; lpとは実数
  n1とは整数; n2とは整数; n3とは整数
  Ek = E(k, PI / 2)
  もし(p1 = p2)なら(4 * Ekを戻す)
  n1 = INT(p1 / 90) + 1
  もし(n1 > 4)なら(n1 = 4)
  lp = Ek * *1 ^ 2)を戻す
●E(k,p)
  lとは実数 = 0
  もし(N > 1)なら
    Iで1からINT(N/2)まで繰り返す
      l = l + __h__[I] * F(__e__[I] * p, k)
  もし(N % 2 = 1)なら
    l = l + __h__[M] * F(__e__[M] * p, k) / 2 #奇数個の場合
  (l * p)を戻す
●EH # 積分点デ-タ
  E1とは整数 = N * (N + 1)
  Iとは整数; Tとは実数; X0とは実数
  PKM1とは実数; PKとは実数; T1とは実数; PKP1とは実数
  DENとは実数; D1とは実数; DPNとは実数; D2PNとは実数; D3PNとは実数; D4PNとは実数
  Uとは実数; Vとは実数; Hとは実数; Pとは実数
  DPとは実数; Hとは実数; XIとは実数; FXとは実数; WIとは実数
  Iで1からMまで繰り返す
    T   = (4 * I - 1) * PI / (4 * N + 2)
    X0  = (1 - (1 - 1 / N) / (8 * N * N)) * COS(T)
    PKM1= 1
    PK  = X0
    Kで2からNまで繰り返す
      T1  = X0 * PK
      PKP1= T1 - PKM1 - (T1 - PKM1) / K + T1
      PKM1= PK
      PK  = PKP1
    DEN = 1 - X0 * X0
    D1  = N * (PKM1 - X0 * PK)
    DPN = D1 / DEN
    D2PN= (2 * X0 * DPN - E1 * PK) / DEN
    D3PN= (4 * X0 * D2PN + (2 - E1) * DPN) / DEN
    D4PN= (6 * X0 * D3PN + (6 - E1) * D2PN) / DEN
    U   = PK / DPN
    V   = D2PN / DPN
    H   = -U * (1 + 0.5 * U * (V + U * (V * V - D3PN / (3 * DPN))))
    P   = PK + H * (DPN + 0.5 * H * (D2PN + H / 3 * (D3PN + 0.25 * H * D4PN)))
    DP  = DPN + H * (D2PN + 0.5 * H * (D3PN + H * D4PN / 3))
    H   = H - P / DP
    XI  = -(X0 + H)
    FX  = D1 - H * E1 * (PK + 0.5 * H * (DPN + H / 3 * (D2PN + 0.25 * H * (D3PN + 0.2 * H * D4PN))))
    WI  = 2 * (1 - XI * XI) / (FX * FX)
    __e__[I] = XI
    __h__[I] = WI

N = 150
M = INT(N / 2) + N % 2
EH

「myfiles」を毎行読んで反復
  もし(対象を「^hs」で正規表現マッチ)ならば
    L = SPLIT(CHOP(対象))
    iで0から15まで繰り返す
    hs[i] = L[i+1]
    続ける
  もし(対象を「^lg[0-9a-f](\S+)」で正規表現マッチ)ならば
    plg = MID(対象,3,1)
    もし(lg = "")なら(lg = plg)
    続ける
  もし(対象を「^ci\s+\S+ \S+ \S+」で正規表現マッチ)ならば
    L = SPLIT(CHOP(対象))
    NF = Lの配列要素数
    r = L[3]
    p1 = 0
    p2 = 0
    w = 1
    もし(NF > 4)なら
      p1 = L[4]
      p2 = L[5]
      w = L[6]
      もし(w > 1)なら
        w = 1 / w
        r = r / w
        p1 = p1 - 90
        p2 = p2 -90
    もし(w = 1)なら
      もし(p1 = p2)なら
        l = 2 * PI
      違えば
        l = (p2 - p1) * PI / 180
    違えば
      l = ARC_L(SQRT(1 - w ^ 2), p1, p2)
      i = INT("${lg}") #16進数→10進数
      j = INT("${plg}") #16進数→10進数
    「h#Lr = {l * r * hs[i] / hs[j]}」を表示

 

 

数値積分ガウスルジャンドルの方法によっています。

*1:n1 + 1) % 2) + E(k, APA(n1, p1) * PI / 180) * (-1) ^ (n1 - 1)
  n2 = INT(p2 / 90) + 1
  もし(n2 > 4)なら(n2 = 4)
  もし(n1 = n2)なら(n1 = n1 + 4)
  n3 = 2 * INT((n2 - 1) / 2) + 5
  lp = lp + Ek * ((n3 - n1) % 4) + E(k, APA(n2, p2) * PI / 180) * (-1) ^ n2
  もし(lp < 0)なら(lp = lp + 4 * Ek)
  lpを戻す
●APA(o,p)
  (90 * (INT((o + 1) / 2) * 2 - 1) - p) * (-1) ^ (o - 1)を戻す
●F(x,k)
  SQRT(1 - (k * SIN(x