【網掛けハッチング】
範囲選択した閉領域の内側に、小円を格子状に配置する外変です。興味のある方はお試しください。(AIで作成)
網掛けハッチング.bat
@echo off
setlocal
goto EXE
REM 網掛けハッチング
REM #jww
REM #cd
REM #h1
REM #hc 範囲を選択してください
REM #g1
REM #gn
REM #bz
REM #hr
REM #e
:EXE
pushd "%~dp0" >nul
set "SCRIPT=%~dp0網掛けハッチング.rb"
if exist "C:\Ruby34-x64\bin\ruby.exe" (
"C:\Ruby34-x64\bin\ruby.exe" "%SCRIPT%"
) else if exist "C:\Ruby33-x64\bin\ruby.exe" (
"C:\Ruby33-x64\bin\ruby.exe" "%SCRIPT%"
) else if exist "C:\Ruby32-x64\bin\ruby.exe" (
"C:\Ruby32-x64\bin\ruby.exe" "%SCRIPT%"
) else if exist "C:\Ruby31-x64\bin\ruby.exe" (
"C:\Ruby31-x64\bin\ruby.exe" "%SCRIPT%"
) else if exist "C:\Ruby30-x64\bin\ruby.exe" (
"C:\Ruby30-x64\bin\ruby.exe" "%SCRIPT%"
) else (
ruby "%SCRIPT%"
)
popd >nul
endlocal
exit /b 0
++++++++++++++++++++++++++++++++
網掛けハッチング.rb
# encoding: Windows-31J
# 網掛けハッチング.rb
Dir.chdir(File.dirname(__FILE__))
input_file = "jwc_temp.txt"
RADIUS_VAL = 0.25 # 半径 0.25mm
INTERVAL_VAL = 2.5 # ピッチ 2.5mm
ARC_DIV = 64 # 円弧の分割数
current_ly, current_lc, current_lt = nil, nil, nil
hs_values = Array.new(16, 1)
current_lg = 0
scale_denom = 1.0
edges = []
def add_edge(edges, a, b)
return if (a[0]-b[0]).abs < 1e-9 && (a[1]-b[1]).abs < 1e-9
edges << { x1: a[0], y1: a[1], x2: b[0], y2: b[1],
min_y: [a[1], b[1]].min, max_y: [a[1], b[1]].max }
end
def add_arc_edges(edges, cx, cy, r, s_deg, e_deg, flat, tilt_deg)
flat = 1.0 if flat == 0
s_rad = s_deg * Math::PI / 180.0
e_rad = e_deg * Math::PI / 180.0
e_rad += 2 * Math::PI if e_rad <= s_rad
tilt = tilt_deg * Math::PI / 180.0
steps = [( (e_rad - s_rad).abs / (2 * Math::PI) * ARC_DIV ).ceil, 8].max
prev_pt = nil
(0..steps).each do |i|
t = s_rad + (e_rad - s_rad) * i / steps.to_f
xt = r * Math.cos(t)
yt = r * flat * Math.sin(t)
px = cx + xt * Math.cos(tilt) - yt * Math.sin(tilt)
py = cy + xt * Math.sin(tilt) + yt * Math.cos(tilt)
add_edge(edges, prev_pt, [px, py]) if prev_pt
prev_pt = [px, py]
end
end
if File.exist?(input_file)
File.open(input_file, "r:Windows-31J") do |f|
f.each_line do |line|
l = line.strip
if l =~ /^hs\s+(.+)/
vals = $1.split.map(&:to_f)
hs_values = vals if vals.size == 16
scale_denom = hs_values[current_lg]
scale_denom = 1.0 if scale_denom <= 0
elsif l =~ /^lg([0-9a-f])$/i
current_lg = $1.to_i(16)
scale_denom = hs_values[current_lg]
scale_denom = 1.0 if scale_denom <= 0
elsif l =~ /^ly([0-9a-f])/
current_ly = $1 if current_ly.nil?
elsif l =~ /^lc(\d+)/ && current_lc.nil?
current_lc = $1
elsif l =~ /^lt(\d+)/ && current_lt.nil?
current_lt = $1
elsif l =~ /^[ \t]*(-?\d+\.?\d*)\s+(-?\d+\.?\d*)\s+(-?\d+\.?\d*)\s+(-?\d+\.?\d*)/
add_edge(edges, [$1.to_f*scale_denom, $2.to_f*scale_denom], [$3.to_f*scale_denom, $4.to_f*scale_denom])
elsif l =~ /^ci\s+/
p = l.split
cx, cy, r = p[1].to_f, p[2].to_f, p[3].to_f
if p.size == 4
add_arc_edges(edges, cx*scale_denom, cy*scale_denom, r*scale_denom, 0, 360, 1.0, 0)
else
add_arc_edges(edges, cx*scale_denom, cy*scale_denom, r*scale_denom, p[4].to_f, p[5].to_f, p[6].to_f, p[7].to_f)
end
end
end
end
end
exit if edges.empty?
def inside?(px, py, edges)
count = 0
edges.each do |e|
if ((e[:y1] > py) != (e[:y2] > py)) &&
(px < (e[:x2] - e[:x1]) * (py - e[:y1]) / (e[:y2] - e[:y1]) + e[:x1])
count += 1
end
end
(count % 2) != 0
end
scale_denom = hs_values[current_lg]
scale_denom = 1.0 if scale_denom <= 0
step = INTERVAL_VAL * scale_denom
half = RADIUS_VAL * scale_denom
ys = edges.map{|e| [e[:y1], e[:y2]]}.flatten
xs = edges.map{|e| [e[:x1], e[:x2]]}.flatten
xmin, xmax, ymin, ymax = xs.min, xs.max, ys.min, ys.max
cx, cy = (xmin + xmax) / 2.0, (ymin + ymax) / 2.0
diag = Math.sqrt((xmax-xmin)**2 + (ymax-ymin)**2)
num = (diag / step).ceil + 2
File.open(input_file, "w:Windows-31J") do |f|
f.puts "h#網掛けハッチング"
f.puts "lc#{current_lc}" if current_lc
f.puts "lt#{current_lt}" if current_lt
u = [Math.cos(Math::PI/4)*step, Math.sin(Math::PI/4)*step]
v = [Math.cos(-Math::PI/4)*step, Math.sin(-Math::PI/4)*step]
(-num..num).each do |i|
(-num..num).each do |j|
px = cx + i * u[0] + j * v[0]
py = cy + i * u[1] + j * v[1]
pts = [[px, py-half], [px, py+half], [px-half, py], [px+half, py]]
if pts.all? { |pt| inside?(pt[0], pt[1], edges) }
f.printf "ci %.6f %.6f %.6f\n", px, py, half
end
end
end
f.puts "ly#{current_ly}" if current_ly
f.puts "lc#{current_lc}" if current_lc
f.puts "lt#{current_lt}" if current_lt
f.puts "hr"
end