円の外にある図形を削除します
@REM jww 外部変形
@REM 円外消去.BAT
@echo off
REM #jww
REM #cd
REM #ht10
REM #ht20
REM #ht40
REM #zz
goto %1
REM #hm【円外消去】 |円外消去|等倍複写|2倍複写|N倍複写|回転複写|
REM #:1
REM #h2
REM #hc 【円外消去】処理範囲を指定してください
REM #g1
REM #bz
REM #9ci 【円外消去】円を指示
REM #e
REM #:2
REM #h2
REM #hc 【等倍複写】処理範囲を指定してください
REM #g1
REM #bz
REM #9ci 【等倍複写】円を指示
REM #0%d 【等倍複写】複写先指示
REM #e
REM #:3
REM #h2
REM #hc 【2倍複写】処理範囲を指定してください
REM #g1
REM #bz
REM #9ci 【2倍複写】円を指示
REM #0%d 【2倍複写】複写先指示
REM #e
REM #:4
REM #h2
REM #hc 【N倍複写】処理範囲を指定してください
REM #g1
REM #bz
REM #9ci 【N倍複写】円を指示
REM #0%d 【N倍複写】複写先指示
REM #c 【N倍複写】倍率指定(無指定:1) : /_N
REM #e
REM #:5
REM #h2
REM #hc 【回転複写】処理範囲を指定してください
REM #g1
REM #bz
REM #9ci 【回転複写】円を指示
REM #0%d 【回転複写】複写先指示
REM #c 【回転複写】倍率指定(無指定:1) : /_N
REM #e
:1
:2
:4
copy jwc_temp.txt jwc_bak.txt
rubyw -x %~f0 %1 %2
GOTO END
:3
copy jwc_temp.txt jwc_bak.txt
rubyw -x %~f0 %1 N2
GOTO END
:5
copy jwc_temp.txt jwc_bak.txt
rubyw -x %~f0 -%1 %2
GOTO END
【円外消去】指定した円の外側を消去
【等倍複写】指定した円の外側を消去して複写
【2倍複写】倍率2倍
【N倍複写】倍率N倍
【回転複写】意味はないけどランダムに回転させてみる
#! ruby
# encoding: SJIS
#%~
# 座標値を取り込む際に円の中心からの相対座標に直す
# 座標値を出力する際
# 【円外消去】では座標を元に戻す
# 他は行列を使って倍率をかけたり回転させたり
include Math
require 'matrix'
$stdout=open("jwc_temp.txt","w")
$stderr=open("tmp_err.txt","w")
def kouten(a,c,b,d) #外積を使って二線(ab,cd)の交点を求める
a=Vector.elements(a.to_a+[0])
b=Vector.elements(b.to_a+[0])
c=Vector.elements(c.to_a+[0])
d=Vector.elements(d.to_a+[0])
cp1=(d-b).cross(b-a)[2]
cp2=(d-b).cross(c-b)[2]
k=cp1/(cp1+cp2)
p=k*(c-a)+a
p=Vector.elements(p.to_a[0..1])
end
opt=ARGV[0].to_i #1:【円外消去】
jwc=open("jwc_bak.txt").read
n=ARGV.grep(/^N/)[0].to_s.gsub(/^N/,"").to_f
n=1.0 if n==0
mx=Matrix[[n,0],[0,n]]
rd=rand(0.0..360.0)
mk=Matrix[[cos(rd*PI/180.0),-sin(rd*PI/180.0)],
[sin(rd*PI/180.0),cos(rd*PI/180.0)]] #回転用行列
vo=Vector[0,0]
cir=jwc.match(/hhp9ci\nci (-?[\d.]+) (-?[\d.]+) (-?[\d.]+)/m).
to_a.map{|e| e.to_f}[1..3]
v0=Vector.elements(cir[0..1])
r1=cir[2]
jwc.split("\n").each{|jw|
if jw.match(/^hq/)
puts "hd" if opt==1
elsif jw.match(/^pt (.*)/) #点の処理
vp=Vector.elements($1.split(" ").map{|f| f.to_f})
vp=vp-v0
if vp.r<r1
puts "pt "+(vp+v0).to_a.join(" ") if opt==1
puts "pt "+(mx*vp).to_a.join(" ") if opt>=2
puts "pt "+(mk*mx*vp).to_a.join(" ") if opt==-5
end
elsif jw.match(/^( -?[\d.]+){4}/) #線の処理
vs,ve=$&.split(" ").map{|e| e.to_f}.
each_slice(2).map{|e| Vector.elements(e)}
vs,ve=vs-v0,ve-v0
vs,ve=ve,vs if vs.r>ve.r
vb=Matrix[[0,-1],[1,0]]*(ve-vs) #90°回転
vh=kouten(vo,vb,vs,ve) #円の中心から線への垂点
if vh.r<r1
vp=(ve-vs)*sqrt(r1**2-(vh.r)**2)/(ve-vs).r+vh
vq=(vs-ve)*sqrt(r1**2-(vh.r)**2)/(ve-vs).r+vh
if vs.r<r1 && ve.r<r1
puts " "+((vs+v0).to_a+(ve+v0).to_a).join(" ") if opt==1
puts " "+((mx*vs).to_a+(mx*ve).to_a).join(" ") if opt>=2
puts " "+((mk*mx*vs).to_a+(mk*mx*ve).to_a).join(" ") if opt==-5
elsif vs.r<r1
puts " "+((vs+v0).to_a+(vp+v0).to_a).join(" ") if opt==1
puts " "+((mx*vs).to_a+(mx*vp).to_a).join(" ") if opt>=2
puts " "+((mk*mx*vs).to_a+(mk*mx*vp).to_a).join(" ") if opt==-5
elsif (ve-vs).dot(vq-vs)>0 && (ve-vs).dot(vp-vs)>0
puts " "+((vq+v0).to_a+(vp+v0).to_a).join(" ") if opt==1
puts " "+((mx*vq).to_a+(mx*vp).to_a).join(" ") if opt>=2
puts " "+((mk*mx*vq).to_a+(mk*mx*vp).to_a).join(" ") if opt==-5
end
end
elsif jw.match(/^ci (.*)/) #円の処理
ci=$1.split(" ").map{|f| f.to_f}
cc=Vector.elements(ci[0,2])
cc=cc-v0 #円弧中心
r2=ci[2] #半径
d=cc.r #円と円の距離
ch=(ci[5] ? ci[5] :1.0) #扁平率
cj=(ci[6] ? ci[6] :0.0) #軸角
if d>r1+r2 #円が離れている場合
next
elsif d<r1-r2 or (cc.r==0 && r1==r2) #円の中に円がある又は円が同一
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} "+ci[3..6].join(" ") if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} "+ci[3..6].join(" ") if opt>=2
if opt==-5 && ci[3] #円弧か楕円
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} "+
ci[3..5].join(" ")+" #{(cj+rd)%360.0}"
elsif opt==-5
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n}"
end
else #交点が存在する場合
if ch<1.0 #楕円の場合はそのまま出力
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} "+ci[3..6].join(" ") if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} "+ci[3..6].join(" ") if opt>=2
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} "+
ci[3..5].join(" ")+" #{(cj+rd)%360.0}" if opt==-5
else
rad=acos((d**2+r1**2-r2**2)/(2*d*r1)) #余弦定理
ma=Matrix[[cos(rad),sin(rad)],[-sin(rad),cos(rad)]]
mb=Matrix[[cos(rad),-sin(rad)],[sin(rad),cos(rad)]]
vp=ma*cc*(r1/d) #交点1
vq=mb*cc*(r1/d) #交点2
vc=Vector[r2,0]
dp=atan2((vp-cc)[1],(vp-cc)[0])*180/PI
dq=atan2((vq-cc)[1],(vq-cc)[0])*180/PI
dp=dp+360.0 if dp<0
dq=dq+360.0 if dq<0
dp,dq=[dp,dq].sort
if ci.size==3 #円の場合
dp,dq=dq,dp if (vc+cc).r<r1 #0°の点が円の外
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} #{dp} #{dq} 1.0 0" if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} #{dp} #{dq} 1.0 0" if opt>=2
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} #{dp} #{dq} "+
"1.0 #{rd}" if opt==-5
else #円弧の場合
ds,de=ci[3]+cj,ci[4]+cj #始角と終角
de=(de-ds<0 ? de-ds+360.0 : de-ds)
dp,dq=[dp,dq].map{|e| e-ds<0 ? e-ds+360.0 : e-ds}.sort
ms=Matrix[[cos(ds*PI/180),-sin(ds*PI/180)],[sin(ds*PI/180),cos(ds*PI/180)]]
if dq<de #交点が2つ
if (ms*vc+cc).r<r1 #始点が円内
dp,dq,de=[dp,dq,de].map{|e| (e+ds)%360}
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} #{ds} #{dp} 1.0 0" if opt==1
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} #{dq} #{de} 1.0 0" if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} #{ds} #{dp} 1.0 0" if opt>=2
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} #{dq} #{de} 1.0 0" if opt>=2
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} #{ds} #{dp} "+
"1.0 #{(cj+rd)%360.0}" if opt==-5
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} #{dq} #{de} "+
"1.0 #{(cj+rd)%360.0}" if opt==-5
else
dp,dq,de=[dp,dq,de].map{|e| (e+ds)%360}
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} #{dp} #{dq} 1.0 0" if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} #{dp} #{dq} 1.0 0" if opt>=2
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} #{dp} #{dq} "+
"1.0 #{(cj+rd)%360.0}" if opt==-5
end
elsif dp<de #交点が1つ
dp,dq,de=[dp,dq,de].map{|e| (e+ds)%360}
if (ms*vc+cc).r<r1 #始点が円内
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} #{ds} #{dp} 1.0 0" if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} #{ds} #{dp} 1.0 0" if opt>=2
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} #{ds} #{dp} "+
"1.0 #{(cj+rd)%360.0}" if opt==-5
else
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} #{dp} #{de} 1.0 0" if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} #{dp} #{de} 1.0 0" if opt>=2
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} #{dp} #{de} "+
"1.0 #{(cj+rd)%360.0}" if opt==-5
end
else de<dp #円弧が円内
dp,dq,de=[dp,dq,de].map{|e| (e+ds)%360}
if (ms*vc+cc).r<r1 #始点が円内
puts "ci "+(cc+v0).to_a.join(" ")+" #{r2} #{ds} #{de} 1.0 0" if opt==1
puts "ci "+(mx*cc).to_a.join(" ")+" #{r2*n} #{ds} #{de} 1.0 0" if opt>=2
puts "ci "+(mk*mx*cc).to_a.join(" ")+" #{r2*n} #{ds} #{de} "+
"1.0 #{(cj+rd)%360.0}" if opt==-5
end
end
end
end
end
else
puts jw
end}
__END__
:END
コメント