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

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

 

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

:パワーシェルで楕円弧の長さ(表示画面のスケール)を計測表示する
@echo off
for /f "delims=:" %%n in ('findstr /n "^#!" %0') do (
  more +%%n %0 | powershell -command -
)
goto:eof

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

#!ここから more +n %0 の n 行目:最初の行は 0 行
function remainder ($x,$y)
{
  [math]::sign($x)*($x % $y)
}
function l ($r,$p1,$p2,$w) # 弧長を計算する
{
    $x=1.0-$w
    if ($x -eq 0) {$s = 0} else {if ($x -gt 0) {$s = 1} else {$s = -1}}
    if ($s -eq -1) {
      $w = 1.0/$w
      $r /= $w
      $p1 -= 90
      $p2 -= 90
    }
  $k = [math]::sqrt(1.0-$w*$w)
  $ek = e $k ([math]::PI/2)
  while ($p1 -lt 0) {$p1 += 360}
  while ($p1 -ge 360) {$p1 -= 360}
  while ($p2 -lt 0) {$p2 += 360}
  while ($p2 -ge 360) {$p2 -= 360}
  if ($p1 -eq $p2) {return 4.0*$ek*$r}
  $n1 = 1 + [int] ($p1/90.0)
  if ($n1 -gt 4) {$n1 = 4}
  $lp = $ek*(remainder ($n1+1) 2)+(e $k (apa $n1 $p1)*[math]::PI/180)*[math]::pow(-1.0,($n1-1))
  $n2 = 1 + [int] ($p2/90.0)
  if ($n2 -gt  4) {$n2 = 4}
  if ($n1 -eq $n2) {$n1 += 4}
  $n3 = 5 + 2 * [int] ( ($n2-1)/2.0)
  $lp += $ek*(remainder ($n3-$n1) 4)+(e $k (apa $n2 $p2)*[math]::PI/180)*[math]::pow(-1.0,$n2)
  if ($lp -lt 0) {$lp += 4.0 * $ek}
  return $lp*$r
}
function apa ($o,$p)
{
  return (90.0* [int] (2*( ($o+1)/2) -1)-$p)*[math]::pow(-1,($o-1))
}
function f ($x,$k)
{
  return [math]::sqrt(1.0-[math]::pow($k*[math]::sin($x),2))
}
function e($k,$p)
{
#    第2種楕円積分 E(p,k) をガウス積分により算定する
    if ($k -eq 0) { return $p }
    $l = 0.0
    foreach ($i in 1..([int] ($n/2.0)))
    {
        $l += $hh[$i]*(f ($ee[$i]*$p) $k)
    }
    if ($n%2 -eq 1) #奇数個の場合
    {
        $l += $hh[$m]*(f ($ee[$m]*$p) $k)/2.0
    }
    return $l*$p
}
function gear ($w=1)
{
    if ( ($w -gt 1) -and ($w -ne 0)) { $w = 1.0 / $w }
    $n  = [int] (12*(1.5/$w)) # 積分点数 12
#    |             
#    +--- 積分点数(扁平率により自動計算)
#         bpa = 1.0   --- n =   18
#               0.5   ---       36
#               0.1   ---      180
#               0.006 ---     3000
        if ($n -gt 300) { $n = 300 }
        
#    計算精度が不要な方は次の行の # 印を削除して下さい。
#    $n = 24

        # 簡単のため n は 偶数のみの扱いとしている
        # 計算ルーチンは奇数個も扱える
        if ($n%2 -eq 1) { $n += 1 }
    $m  = ($n+ (remainder $n 2))/2

    $ee = @(); foreach ($i in 0..$m) { $ee += 0 }
    $hh = @(); foreach ($i in 0..$m) { $hh += 0 }

    $e1 = $n*($n+1.0)
#    ここから Fortran Program を パワーシェル に移植した
    foreach ($i in 1..$m)
    {
        $t   = (4.0*$i-1.0)*[math]::PI/(4.0*$n+2.0)
        $x0  = (1.0-(1.0-1.0/$n)/(8.0*$n*$n))*[math]::cos($t)
        $pkm1= 1.0
        $pk  = $x0
        foreach ($k in 2..$n)
        {
            $t1   = $x0*$pk
            $pkp1 = $t1-$pkm1-($t1-$pkm1)/$k+$t1
            $pkm1 = $pk
            $pk   = $pkp1
        }
        $den  = 1.0-$x0*$x0
        $d1   = $n*($pkm1-$x0*$pk)
        $dpn  = $d1/$den
        $d2pn = (2.0*$x0*$dpn-$e1*$pk)/$den
        $d3pn = (4.0*$x0*$d2pn+(2.0-$e1)*$dpn)/$den
        $d4pn = (6.0*$x0*$d3pn+(6.0-$e1)*$d2pn)/$den
        $u  = $pk/$dpn
        $v  = $d2pn/$dpn
        $h  = -1.0*$u*(1.0+0.5*$u*($v+$u*($v*$v-$d3pn/(3.0*$dpn))))
        $pp = $pk+$h*($dpn+0.5*$h*($d2pn+$h/3.0*($d3pn+0.25*$h*$d4pn)))
        $dp = $dpn+$h*($d2pn+0.5*$h*($d3pn+$h*$d4pn/3.0))
        $h -= $pp/$dp
        $xi = $x0+$h
        $fx = $d1-$h*$e1*($pk+0.5*$h*($dpn+$h/3.0*($d2pn+0.25*$h*($d3pn+0.2*$h*$d4pn))))
        $wi = 2.0*(1.0-$xi*$xi)/($fx*$fx)
        $ee[$i] = $xi
        $hh[$i] = $wi
    }
    return ($n,$m,$ee,$hh)
}
(gc jwc_temp.txt) | %{
  switch -regex -case ($_)
  {
    "^hs" {
      $F = [regex]::split($_,' +')
      $i=0
      $hs = @{}
      $F[1..$F.length] | %{ $hs[$i] = [double] $_ ; $i++ }
      $hs += @{'0'=$($hs[0]);'1'=$($hs[1]);'2'=$($hs[2]);'3'=$($hs[3]);'4'=$($hs[4]);'5'=$($hs[5])}
      $hs += @{'6'=$($hs[6]);'7'=$($hs[7]);'8'=$($hs[8]);'9'=$($hs[9])}
      $hs += @{a=$($hs[10]);b=$($hs[11]);c=$($hs[12]);d=$($hs[13]);e=$($hs[14]);f=$($hs[15])}
    }
    "^lg[0-9a-f]" {
      $plg = $_.substring(2,1)
      if ($lg -eq $null) {$lg = $plg}
    }
    "^hhp[1-9][0-9]?(ln|ci|ch)" {
      $cin = $_ -replace "^hhp","" -replace "(ln|ci|ch)",""
    }
    "^ci" {
      $F = [regex]::split($_,' +')
      $a = $($F[1..$F.length] | %{ [double] $_ })
      $p = $hs[$lg]/($hs[$plg])
      $x,$y,$r=$a[0,1,2]
      if ($F.length -eq 4)
      {
        $p1,$p2,$w,$d=0,0,1,0
      }
      if ($F.length -eq 8)
      {
        $p1,$p2,$w,$d=$a[3,4,5,6]
      }
      $n,$m,$ee,$hh = gear $w
      #"h#Lr = $(l ($r*$p) $p1 $p2 $w)"
      "h#円弧長 L = $([math]::round( (l ($r*$p) $p1 $p2 $w), 3))"
    }
  }
} | sc jwc_temp.txt

#ここまで powershell は 文末に必ず空白行を置いてください