jw_cad 外部変形 - (685) パワーシェルで円弧の端点に矢印を描く -

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

 

パワーシェルで円弧の端点に矢印を描く

:パワーシェルで円弧の端点に矢印を描く
@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 #cd
REM #e

#!ここから more +n %0 の n 行目:最初の行は 0 行
. ./draw
function cipoint ($ci,$pm=1)
{
  $x,$y,$r,$p1,$p2,$w,$d = $ci
  $d *= [math]::PI/180
  $co=[math]::cos($d)
  $si=[math]::sin($d)
  $q = $(if ($pm -eq -1) {$p1} else {$p2})
  $q *= [math]::PI/180.0
  $xr=$r*[math]::cos($q)
  $yr=$r*[math]::sin($q)*$w
  $a=[math]::atan2($yr/$w,$xr*$w)+$d
  return ( ($x+$xr*$co-$yr*$si),($y+$xr*$si+$yr*$co)),$a
}
(gc jwc_temp.txt) | %{
  switch -regex -case ($_)
  {
    "^hp[1-9][0-9]?(ln|ci|ch)" {
      $pt = ([regex]::split($_,' +')[1,2] | %{ [double] $_ })
    }
    "^ci" {
      $F = [regex]::split($_,' +')
      $x,$y,$r = ($F[1..3] | %{ [double] $_ })
      $p1,$p2,$w,$d=0,0,1,0
      if ($F.length -eq 8)
      {
        $p1,$p2,$w,$d=($F[4..7] | %{ [double] $_ })
      }
      $ci = $x,$y,$r,$p1,$p2,$w,$d
      'bz'
      $size = 5 #矢印の長さ( 図寸 )
      $xang = 45 #矢印の交角( ゚ )
      $xan2 = 120 #矢尻の交角( ゚ )
      $pt1,$a1 = cipoint $ci -1
      $pt2,$a2 = cipoint $ci  1
      $l1 = ptdist $pt $pt1
      $l2 = ptdist $pt $pt2
      $pm = $(if ($l1 -le $l2 ) { -1 } else { 1 })
      if ($pm -eq -1)
      {
        arrow $pt1 ($a1+[math]::PI/2) $pm $size $xang $xan2
      } elseif ($pm -eq 1)
      {
        arrow $pt2 ($a2+[math]::PI/2) $pm $size $xang $xan2
      }
    }
  }
} | sc jwc_temp.txt

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

 

○draw.ps1

# ユーザ定義関数
function sgn ($x)
{
  [math]::sign($x)
}
function remainder ($x,$y)
{
  [math]::sign($x)*($x % $y)
}
function hypot ($x,$y)
{
  [math]::sqrt($x*$x+$y*$y)
}
function lnlength ($ln) #線長を返す
{
  $x1,$y1,$x2,$y2 = $ln
  hypot ($x2-$x1) ($y2-$y1)
}
function lnslope ($ln) #線の角度を返す
{
  $x1,$y1,$x2,$y2 = $ln
  [math]::atan2($y2-$y1,$x2-$x1)
}
function ln_hpdist ($ln,$hp) #線と点の最短距離を返す
{
  $x = $hp + $ln[0..1]
  return (lnlength $x)*[math]::sin( (lnslope $ln)-(lnslope $x))
}
function ln_hpsnap ($ln,$hp) #線の吸着点を返す, ±を逆にした 060824
{
  $t = ln_hpdist $ln $hp
  $d = lnslope $ln
  return ($hp[0] + $t * [math]::sin($d)),($hp[1] - $t * [math]::cos($d))
}
function lnmove ($ln,$b,$pmy=1) #線 ln を直交距離 b だけ pmy の方向に平行移動する
{
  $x1,$y1,$x2,$y2 = $ln
  $d  = lnslope $ln
  $co = [math]::cos($d)
  $si = [math]::sin($d)
  $x1 -= $b*$si*$pmy
  $y1 += $b*$co*$pmy
  $x2 -= $b*$si*$pmy
  $y2 += $b*$co*$pmy
  return $x1,$y1,$x2,$y2
}
function inters ($ln1,$ln2) #2直線の交点の座標リストを返す
{
  $1,$2,$3,$4 = $ln1
  $dx1 = $3 - ($x1=$1)
  $dy1 = $4 - ($y1=$2)
  $m1 = $(if ($dx1 -eq 0) {1e20} else {$dy1/$dx1})
  $1,$2,$3,$4 = $ln2
  $dx2 = $3 - ($x2=$1)
  $dy2 = $4 - ($y2=$2)
  $m2 = $(if ($dx2 -eq 0) {1e20} else {$dy2/$dx2})
  $aa = $m1 - $m2
  if ( $aa -ne 0 ) {
    $u1 = $y1 - $m1 * $x1
    $u2 = $y2 - $m2 * $x2
    return ( ($u2-$u1)/$aa),( ($m1*$u2-$m2*$u1)/$aa)
  } else {
    "he処理できません"
  }
}
function ptdist ($pt1,$pt2)
{
  hypot ($pt2[0]-$pt1[0]) ($pt2[1]-$pt1[1])
}
function polarto ($pt,$r,$d)
{
  return ($pt[0]+$r*[math]::cos($d)),($pt[1]+$r*[math]::sin($d))
}
function arrow ($pt1,$d,$pm,$size=3,$xang=45,$xan2=120)
{
    $l = -$size*$pm
    $a = $xang*[math]::PI/180/2.0
    $pt2 = polarto $pt1 $l ($d-$a)
    $pt4 = polarto $pt1 $l ($d+$a)
    if ($xan2 -eq 180)
    {
        $sl = $pt1+$pt2+$pt4
    } else {
        $c = [math]::cos($a) - [math]::sin($a)*[math]::tan( (90.0-$xan2/2.0)*[math]::PI/180)
        $pt3 = polarto $pt1 ($l*$c) $d
        $sl = $pt1+$pt2+$pt3+$pt4
    }
    "sl $sl"
}