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

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

 

jscriptで楕円弧の長さ(表示画面のスケール)を計測表示する

/* jscriptで楕円弧の長さ(表示画面のスケール)を計測表示する
@cls & echo off
copy jwc_temp.txt myfiles > nul
cscript //nologo //e:jscript %0 > jwc_temp.txt
goto:eof

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

function int(a){
  return a < 0 ? Math.ceil(a) : Math.floor(a)
}

function apa(o, p){
  return (90.0 * (2 * int( (o + 1) / 2) - 1) - p) * Math.pow(-1, o - 1)
}

function E2(p, k){ //第2種楕円積分(無限級数解)
  var n, e, a, s_n, c, s, j
  if (k == "" || k == null) {
    k = p
    p = Math.PI / 2
  }
  //if (k < 0 || 1 < k) { WScript.Echo("h#e()計算できませんでした\n"); return 0 }
  if (k > 1-1e-15) { return Math.sin(p) }
  n = 2.0
  e = 0.0
  a = 1.0
  s_n = p
  c = Math.cos(p)
  s = Math.sin(p)
  j = 0
  while (Math.abs(a * s_n) > 1e-20 || j < 30000) {
    e += a * s_n
    a *= (n - 3.0) / n * k * k
    s_n = ( (n - 1.0) * s_n - Math.pow(s, n - 1.0) * c) / n
    n += 2
    j += 1
  }
  return e
}

function arc_l(r, p1, p2, w){
  var ek, lp, n1, n2, n3, k
  with (Math) {
    ek = E2(PI / 2, k = sqrt(1.0 - w * w))
    if (p1 == p2) p2 += 360;
    while (p1 < 0) p1 += 360;
    while (p1 >= 360) p1 -= 360;
    while (p2 < 0) p2 += 360;
    while (p2 >= 360) p2 -= 360;
    if (p1 == p2) {
      lp = 4.0 * ek
    } else {
    lp = int(abs(p2 - p1) / 360.0) * 4.0 * ek
      n1 = 1 + int(p1 / 90.0)
      if (n1 > 4) n1 = 4;
      lp += ek * ( (n1 + 1.0) % 2) + E2(apa(n1, p1) * PI / 180, k) * Math.pow(-1.0, n1 - 1)
      n2 = 1 + int(p2 / 90.0)
      if (n2 > 4) n2 = 4;
      if (n1 == n2) n1 += 4;
      n3 = 5 + 2 * int( (n2 - 1.0) / 2.0)
      lp += ek * ( (n3 - n1) % 4) + E2(apa(n2, p2) * PI / 180, k) * Math.pow(-1.0, n2)
      if (lp < 0.0) lp += 4.0 * ek;
        if (lp > 4.0 * ek) lp -= 4.0 * ek;
    }
  }
  return r * lp
}

function hex(x){
  if (x == 10) return "a";
  if (x == 11) return "b";
  if (x == 12) return "c";
  if (x == 13) return "d";
  if (x == 14) return "e";
  if (x == 15) return "f";
  return x
}

hs = []
lg = ""

f = WScript.StdIn
while (! f.AtEndOfStream) {
  F = ($_ = f.ReadLine()).split(/\s+/)
      if (/^hs/i.test($_)) { //hs スケール
        str = F.slice(1)
        for (i in str) hs[hex(i)] = str[i] * 1.0;
      }
      if (/^lg[A-F0-9]/i.test($_)) { //lg レイヤグループ
        plg = $_.substr(2, 1).toLowerCase(); if( lg == "" ) lg = plg;
      }
      if (/^ci/i.test($_)) { //ci 指示円
        ci1 = F.slice(1)
        p = hs[lg] / hs[plg]
        for (i in ci1) ci1[i] *= 1.0;
        ci1[2] *= p
        if (ci1.length == 3) ci1 = ci1.concat(0, 360, 1, 0);
      }
}

if (ci1[5] > 1-1e-15) {
  p1 = ci1[3]
  p2 = ci1[4]
  p = p2 - p1
  while (p <= 1e-15) p = p + 360;
  while (p >= 360) p = p - 360;
  lr = ci1[2] * p / 180.0 * Math.PI
} else {
  lr = arc_l(ci1[2], ci1[3], ci1[4], ci1[5])
}
g = WScript.StdOut
g.WriteLine("h#円弧長 L = " + lr.toFixed(3))