節間線種変更

作成理由

  • 節間消去と同じ操作で線種変更したいとの要望がjww掲示板で上がっていた
  • 大変そうな割に要望を満たすレベルのものが作れる気がしなくてためらってたけど、出来る範囲で作ってみる

制限事項

  • 円、円弧、楕円等については一切無視して直線だけを処理します
  • 変更後の線種、線色は現在の線種、線色になります
  • 線のクリックではなく連線で交差した線を対象にするようにしました
    • そのほうが便利そうかなと思ったのと、将来、拡張して円弧を対象に含めることがあるかもしれないため
  • 外部変形の性質上、寸法属性を持つ寸法図形はどちらかが解除されるはずです(うろ覚え)

外部変形

  • ruby 1.8.7 (2010-12-23 patchlevel 330) [i386-mingw32] にて動作確認しています

REM 節間線種変更.bat
CHCP 932
echo off
REM #jww
REM #cd
goto %EXE
REM #h4
REM #1- 連線 【1】位置指示 (L)free (R)Read 
REM #2  連線 【2】位置指示 (L)free (R)Read 
REM #bz
REM #e
:EXE
copy jwc_temp.txt temp.txt
REM C:\ruby187\bin\ruby -Ks -x %~f0
REM C:\Ruby24\bin\ruby -Ks -x %~f0
REM C:\Ruby32\bin\ruby -Ks -x %~f0
ruby -Ks -x %~f0
GOTO END

◎コメント
◎バッチファイル名は自由
◎以下 ruby スクリプト部分

#! ruby
# encoding: SJIS

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

include Math
require "matrix"

#初期設定値
ds=0.001  #切断線の最小値(図形寸法)
lc=0      #変更後の線色(0-9)0は現在の線色
lt=0      #変更後の線種(0-9)0は現在の線種

#主な変数
v0=Vector[1000.0,1000.0] #単位ベクトル*1000*2**0.5
m9=[]                    #全ての線の行列
#m0                      #連線の行列
#a0                      #連線の線の定数
m1=[]                    #連線に交差する線の行列
a1=[]                    #連線に交差する線の定数
p1=[]                    #連線とm1との交点(配列)
m2=[]                    #m1に交差する線の行列(始点側)
a2=[]                    #m1に交差する線の定数(始点側)
p2=[]                    #m1とm2の交点(始点側)
m3=[]                    #m1に交差する線の行列(終点側)
a3=[]                    #m1に交差する線の定数(終点側)
p3=[]                    #m1とm2の交点(終点側)
p2a,p3a=[],[]

class Matrix
  def kousa?(m8,ds=-0.1**10) #線のが交差するかの確認
    v0=Vector[1000.0,1000.0]
    return false unless m8.regular?
    a8=m8.inv*v0
    e9=self
    return false unless e9.regular?
    a9=e9.inv*v0
    return false unless Matrix[a9.to_a,a8.to_a].regular?
    p9=Matrix[a9.to_a,a8.to_a].inv*v0
    v11=Vector.elements(m8.to_a[0])
    v12=Vector.elements(m8.to_a[1])
    v21=Vector.elements(e9.to_a[0])
    v22=Vector.elements(e9.to_a[1])
    return (v12-v11).r-(p9-v11).r>ds && (v12-v11).inner_product(p9-v11)>-0.1**10 &&
      (v22-v21).r-(p9-v21).r>ds && (v22-v21).inner_product(p9-v21)>-0.1**10
  end
end
ar=open("temp.txt").readlines.map{|e| e.chomp}
lc=ar.find{|e| %r|^lc|=~e}.sub("lc","").to_i if lc==0
lt=ar.find{|e| %r|^lt|=~e}.sub("lt","").to_i if lt==0
h1=ar.find{|e| %r|^hp1|=~e}.split[1..-1].map{|e| e.to_f}
h2=ar.find{|e| %r|^hp2|=~e}.split[1..-1].map{|e| e.to_f}
m0=Matrix[h1,h2]
a0=m0.inv*v0
m9=ar.select{|e| %r|^ [\d-]|=~e}.map{|e|
  e=e.split.map{|f| f.to_f}
  Matrix[[e[0],e[1]],[e[2],e[3]]]}
m1=m9.select{|e| e.kousa?(m0)}
a1=m1.map{|e| m=e;m.inv*v0 if m.regular?}
p1=a1.map{|e| m=Matrix[a0.to_a,e.to_a];m.inv*v0 if m.regular?}
m1.each_with_index{|e,i|
  m2 << m9.select{|f| f.kousa?(Matrix[e.to_a[0],p1[i].to_a],ds)}}
m1.each_with_index{|e,i|
  m3 << m9.select{|f| f.kousa?(Matrix[e.to_a[1],p1[i].to_a],ds)}}
a2=m2.map{|e| e.map{|f| m=f;m.inv*v0 if m.regular?}}
a3=m3.map{|e| e.map{|f| m=f;m.inv*v0 if m.regular?}}
a2.each_with_index{|e,i| p2 << e.map{|f|
  m=Matrix[a1[i].to_a,f.to_a];m.inv*v0 if m.regular?}}
a3.each_with_index{|e,i| p3 << e.map{|f|
  m=Matrix[a1[i].to_a,f.to_a];m.inv*v0 if m.regular?}}
p2.each_with_index{|e,i| p2a << e.compact.sort_by{|f| (f-p1[i]).r}[0]}
p3.each_with_index{|e,i| p3a << e.compact.sort_by{|f| (f-p1[i]).r}[0]}
p2,p3=p2a,p3a
ha={}
m1=m1.map{|e| e.to_a.flatten}
m1.each_with_index{|e,i| ha[e]=[p2[i].to_a,p3[i].to_a]}
lc0,lt0=0,0
open("temp.txt").readlines.each{|e|
  if %r|^hq|=~e
    puts "hd"
  elsif %r|lc(\d+)|=~e
    lc0=$1.to_i
    puts e
  elsif %r|lt(\d+)|=~e
    lt0=$1.to_i
    puts e
  elsif %r|^ [\d-]|=~e
    e=e.split.map{|e| e.to_f}
    if m1.to_a.include?(e)
      h=ha[e]
      if h[0]==[]
        puts " #{h[1][0]} #{h[1][1]} #{e[2]} #{e[3]}"
        puts "lc#{lc}" if lc!=lc0
        puts "lt#{lt}" if lt!=lt0
        puts " #{e[0]} #{e[1]} #{h[1][0]} #{h[1][1]}"
        puts "lc#{lc0}" if lc!=lc0
        puts "lt#{lt0}" if lt!=lt0
      elsif h[1]==[]
        puts " #{e[0]} #{e[1]} #{h[0][0]} #{h[0][1]}"
        puts "lc#{lc}" if lc!=lc0
        puts "lt#{lt}" if lc!=lc0
        puts " #{h[0][0]} #{h[0][1]} #{e[2]} #{e[3]}"
        puts "lc#{lc0}" if lc!=lc0
        puts "lt#{lt0}" if lt!=lt0
      else
        puts " #{e[0]} #{e[1]} #{h[0][0]} #{h[0][1]}"
        puts " #{h[1][0]} #{h[1][1]} #{e[2]} #{e[3]}"
        puts "lc#{lc}" if lc!=lc0
        puts "lt#{lt}" if lt!=lt0
        puts " #{h[0][0]} #{h[0][1]} #{h[1][0]} #{h[1][1]}"
        puts "lc#{lc0}" if lc!=lc0
        puts "lt#{lt0}" if lt!=lt0
      end
    else
      puts " "+e.join(" ")
    end
  else
    puts e
  end
}
__END__
:END

追記(2024/4/7)

  • 多分だけどfukuokaさんは複数のrubyをインストールされててver3.2.1を使ってるつもりで実はver1.**が起動してたんじゃないかと思います
  • dotとかmap.with_indexがないってエラーになるのはver1ですし
  • 再インストールすることによって環境変数のPathが変更されてver3がちゃんと起動するようになったんじゃないかって思ってるんですが実際のところはよく分かりません
  • で、これからですが
対象計算方法注釈
直線と直線連立方程式を解くいまここ
直線と円弧三角関数を使って計算面倒くさい
直線と楕円弧楕円を軸角分回転させてXY方向に異倍率を掛けて直線と円弧として計算して戻すもっと面倒くさい
楕円弧と楕円弧昔、計算したときは交点の両側から交点へ近づけるようにして求めた気がするとても手に負えない
  • なんて風に進んでいくところで、正直、考えるのもうんざりなんて思ってたところ、AFさんがちゃんとしたのを作ってくれたので全面的にそちらを推奨
  • ただ選択肢があることは良いことだって思うので要望等があれば現在の仕様の範囲内でメンテナンスしていきます
  • R.Nさん、banさん確認ありがとうございました
  • 2024年4月7日 10:19 AMのR.Nさんのコメントに対しては私の理解が追いつかないので保留とさせてください

コメント

  1. R.N より:

    こんにちは、

    「節間線種変更.bat」を使用させて頂きました。(感謝です!!)
    操作方法の問題かもですが、教えて下さい。

    jww作図画面で、井桁を作図し、交点に”点”を打って実行してみました。(”点”は不要でしょうが)
    図形上部横線の左端点を右クリック、続けて、同右端点を右クリックしました。

    結果(tmp_err.txt)
    C:/jww/[外部変形]/010_sugi/節間線種変更/節間線種変更1.bat:65:in `kousa?’: undefined method `dot’ for Vector[132.690265486725, 0.0]:Vector (NoMethodError)
    from C:/jww/[外部変形]/010_sugi/節間線種変更/節間線種変更1.bat:80
    from C:/jww/[外部変形]/010_sugi/節間線種変更/節間線種変更1.bat:80:in `select’
    from C:/jww/[外部変形]/010_sugi/節間線種変更/節間線種変更1.bat:80

    となり、実行できませんでした。
    よろしくお願いします。

  2. R.N より:

    消去コマンドで、コントロールバーの、□ 節間消し にチェックして、線を左クリックすると、
    端点~交点、交点同士、交点~端点 のように消去できますが—

  3. ban より:

    外部変形有難うございます。
    ruby 1.8.6 で動作する事を確認しました。

  4. R.N より:

    更新、ありがとうございます。

    2024.04.03、2024.04.03 双方、ruby 1.8.7 (2013-06-27 patchlevel 374) [i386-mingw32] を使っています。
    2024.04.03 公開の方は、問題なく動作しました。

    分かりにくいと思ったことが、どこをを指示したらどの線が変更できるのか?(Free,Read の指定方法)
    左クリックで、指示線自体(区間)を変更できたらと思いましたが、どうでしょう。
    よろしくお願いいたします。

  5. R.N より:

    こんにちは、

    >2024年4月7日 10:19 AMのR.Nさんのコメントに対しては私の理解が追いつかないので保留とさせてください

    何度か指示点位置を試して、(L)Freeで、指示点1~指示点2の位置を、変更線を横断するように指定したら、いいように思いました。
    (R)Read指定でも、同様かと思いますが、この場合、どの線が変更されるのか、想定しにくい場合が—

    素人の要望で、すみませんでした。

  6. R.N より:

    追記(書き漏れしました)

    前記(L,R 指定方法)で、複数線を跨って指定しても、線選択・線変更、を確認しました。