自在切取

作成理由

  • 連続指示点で囲った範囲の内側(または外側)を切り取って別のレイヤに移動したい。

外部変形

  • rubyをインストールして利用して下さい。
  • ruby1.87とruby2.65で動作確認しています。
REM 自在切取
echo off
REM #jww
REM #cd
goto %1
REM  #hc【自在切取】 ボタンを選択して下さい。
REM  #hm【自在切取】 |内側切取[L]|外側切取[R]|
REM  #:1
REM  #g0
REM  #h2
REM  #hc 処理範囲を指定してください
REM  #ht10
REM  #ht20
REM  #ht30
REM  #ht40
REM  #zz
REM  #1- 【内側切取】点を指示  (L)free,(R)Read
REM  #99#
REM  #c レイヤ指定( 0~F 無指定:F ) : /_L
REM  #e
REM  #:2
REM  #g0
REM  #h2
REM  #hc 処理範囲を指定してください
REM  #ht10
REM  #ht20
REM  #ht30
REM  #ht40
REM  #zz
REM  #1- 【外側切取】点を指示  (L)free,(R)Read
REM  #99#
REM  #c レイヤ指定( 0~F 無指定:F ) : /_L
REM  #e

:1
copy jwc_temp.txt jwc_bak.txt
rubyw -x %~f0 %1 %2
GOTO  END
:2
copy jwc_temp.txt jwc_bak.txt
rubyw -x %~f0 %1 %2
GOTO  END

【内側切取】:囲んだ線に対して内側をレイヤ移動します。
【外側切取】:囲んだ線に対して外側をレイヤ移動します。

制限事項:
直線を処理します。
点、円弧、文字、楕円は処理できません。

#~
#! ruby
# encoding: SJIS

include Math
require 'matrix'

$stdout=open("jwc_temp.txt","w")
$stderr=open("tmp_err.txt","w")

class Vector
  def cross(v2) #外積計算
    v1=self
    return Vector.elements([0,0,v1[0]*v2[1]-v1[1]*v2[0]])
  end
end


class Array
  def kouten(ln2) #交点計算
    ln1=self
    as=Vector.elements(ln1[0,2]+[0])
    ae=Vector.elements(ln1[2,2]+[0])
    bs=Vector.elements(ln2[0,2]+[0])
    be=Vector.elements(ln2[2,2]+[0])
    va=ae-as
    vb=be-bs
    c1=va.cross(bs-as)
    c2=va.cross(be-as)
    c3=vb.cross(as-bs)
    c4=vb.cross(ae-bs)
    d1=c1.r/va.r
    d2=c2.r/va.r
    pt=bs+vb.*(d1/(d1+d2))
    if vb.cross(as-bs)==vb.cross(ae-bs) or c1[2]*c2[2]>0 or c3[2]*c4[2]>0
      return nil
    else
      return pt.to_a[0,2]
    end
  end
  def on?(pt) #線上点判定
    ln1=self
    as=Vector.elements(ln1[0,2])
    ae=Vector.elements(ln1[2,2])
    be=Vector.elements(pt)
    va=ae-as
    vb=be-as
    if (va.inner_product(vb)-va.r*vb.r).abs<0.0001
      return true
    else
      return nil
    end
  end
end

op1=ARGV[0].to_i #1:【内側切取】 2:【外側切取】
op2="f"
op2=ARGV[1].to_s.gsub(%r|^L|,"")
op2="f" unless %r|^0-9a-fA-F|=~op2

hp=[] #指示点配列
lp=[] #外形線配列
ln=[] #処理線配列
p0=[] #範囲の外側の点
pt=[] #外形線と処理線の交点の配列
ly="" #現在のレイヤ

jt=open("jwc_bak.txt").readlines.map{|e| e.chomp}
hp=jt.select{|e| %r|^hp\d+- (.*)|=~e}.
  map{|e| e.split(" ")[1,2].map{|f| f.to_f}}
hp.each_with_index{|e,i| lp << e+hp[(i+1)%hp.size]}
ln=jt.select{|e| %r|^ [\d-]|=~e}.
  map{|e| e.split(" ").map{|f| f.to_f}}.uniq
p0=(ln+hp).flatten.each_slice(2).to_a.sort[0].map{|e| e-1}

#外形線と処理線の交点を求める
lp.map{|e| ln.map{|f|
  pt << e.kouten(f) if e.kouten(f)}}

jt.each{|e|
  if %r|^hq|=~e
    puts "hd"
  elsif %r|^ly|=~e
    ly=e.gsub("ly","")
  elsif %r|^ [\d-]|=~e
    le=e.split(" ").map{|f| f.to_f}
    pa=pt.select{|e| le.on?(e)}
    pa+=[le[0,2],le[2,2]]
    pa=pa.sort
    la=p0+pa[0]
    lb,lc,ld=[],[],[]
    pa.each_with_index{|e,i| lb << e+pa[i+1] if pa[i+1]}
    lc=lb.each_slice(2).map(&:first)
    ld=lb-lc
    n=0
    lp.map{|e| n+=1 if e.kouten(la)}
    lc,ld=ld,lc if n%2==1 #外形線内側
    lc,ld=ld,lc if op1==2 #外側消去
    lc.each{|e| puts " "+e.join(" ")}
    if ld!=[]
      puts "ly#{op2}"
      ld.each{|e| puts " "+e.join(" ")}
      puts "ly#{ly}"
    end
  else
    puts e
  end
}
__END__
:END

コメント

  1. R.N より:

    こんばんは、
    外変「自在切取」について、

    レイヤ設定が、”f”にしかならないので、
    #op2=”f”
    op2=ARGV[1].to_s.gsub(%r|^L|,””)
    op2=”f” unless %r|^[a-fA-F0-9]|=~op2
    と、してみましたが—

    データ移動について、
    境界線上のデータを移動データ側にできれば、
    スッキリするかと思いましたが—
    (私には無理ですので)
    よろしくお願いします。