JwRuby 外部変形をRubyオブジェクトにマッピング

JwRuby

 Jw_cadの外部変形で扱う情報(jwc_temp.txt)を、Rubyのオブジェクト指向に合わせて解析・変換するライブラリを公開しました。Rubyらしさ・RubyとJw_cadを馴染ませることを心がけて作成しているので、Rubyを扱える方なら違和感なく綺麗なコードが書けると思います。
 まだ対応していない機能も多々あります。現在のalpha版では、ブロック図形やソリッド図形などには対応してなく、うまく読み込めないので注意してください。

JwRubyの特徴

 以下の特徴があります。

jwc_temp.txtの読み込み・書き出しを意識せず扱える

 処理は全てブロック内で行い、ブロック終了後に書き出されます。また、テスト用に入力先・出力先(デフォルトはどちらもjwc_temp.txt)を変更できます。また、あらかじめjwc_temp.txtを用意しておくことで、通常のコマンドプロンプトからのデバッグもできます。

Jwr.start(:input => "temp.txt", :output => "test.txt"){|jw|
  ...
}
線や点など、図形を全てオブジェクトにマッピング

 jwc_temp.txtに書き出された基本図形をRubyオブジェクトに変換し、配列にまとめています。また、Shapeクラスを継承してメソッドを追加することで、ユーザ定義図形を作ることもできます。

jwc_temp.txt表記の命令を変換

 jwc_temp.txtの表記に別名を付けています。オリジナルの名前でも扱うことができ、その命令に区切り無しで数値が含まれる場合はnに変換した名前になります。

  • lc%d => line_color, またはlcn
  • lt%d => line_type, またはltn
描画系のメソッド

 図形オブジェクトを書き出すメソッドJwr#drawと、基本図形を書き出すJwr#line, circle, pointなどの描画系メソッドを用意しています。jw.circle(0, 0, 100)はjw.draw(Circle.new(0, 0, 100))と等価で、jwc_temp.txtにはci 0 0 100と出力されます。
 その他、jwc_temp.txtの命令をマッピングしたメソッド群があります。

JwRubyで対応していない記述

 jw.write("foo 1 2")と書くことで、JwRubyで対応していない機能も書き出すことができます。

簡単な機能説明

 基本的にJwr.start{|jw| .. }のブロック内で処理を行い、以下はそうした場合のブロック内のコードです。

図形 (shape)

  • 線: Line
  • 円: Circle
  • 文字: Text
  • 点: Point
  • 曲線: CurveLine

 図形は、Shapeクラスを継承したクラスのインスタンスとして表現していて、「jwc_temp.txtから読み込んだもの」と「ユーザがインスタンス化するもの」があります。前者は全てjw.shapesに配列で格納されており、後者は自由に作成できます。図形を作っただけでは描画されず、jw.drawに渡すことでjwc_temp.txtに描画処理が書き込まれます。図形を作成する際の引数は、概ねjwc_temp.txtの記述に沿っています。

jw.shapes.map{|shape| shape.class }
#=> [Line, Line, Line, Circle]

line = Line.new(0, 0, x, y)
jw.draw(line.move(vx, vy))

図面情報

 図面のデータや、図形以外の情報は、jw.drawingに格納されています。Drawingクラスのソースに、対応している機能とエイリアスが載っています。

jw.drawing.layer  #=> 0
jw.drawing.font   #=> MS ゴシック

基準点(指示点)

 基準点はjw.drawing.pointにハッシュで格納されていますが、jw[key]で得ることができます。キーは数値でも文字列でも構いません。それぞれの座標値は[x, y]の配列です。

jw.drawing.point["1-"] == jw[1]  #=> true
x, y = jw[1]

レイヤ・レイヤグループ

 全レイヤ・レイヤグループは、jw.layer / jw.layer_groupに配列(0-15)で格納されています。それぞれのLayer / LayerGroupオブジェクトには以下のメソッドがあります。

  • name
  • number
  • edit?
  • visible?
  • protect1?
  • protect2?
jw.layer[0].visible?   #=> true
jw.layer[0].protect1?  #=> false

サンプル

最低限必要な記述

#! ruby -Ks
require "jwr"

Jwr.start{|jw|
  # ここに処理を記述
  # 以下の説明では処理部分のみ記述
}

始点と終点を得て線を引く

x1, y1 = jw["1-"]  # 単純に数値でも可(jw[1])
x2, y2 = jw[2]
jw.line(x1, y1, x2, y2)

選択範囲全てをx軸に1000ずらす

jw.delete_selected  # 選択された図形を削除(hd)
jw.shapes.each{|shape|
  jw.draw(shape.move(1000, 0))
}

選択範囲内の点の個数を指定点に書き込む

n = jw.shapes.count{|e| e.point? }
x, y = jw[1]
jw.text("h", x, y, 0, 0, n)  # 引数はjwc_temp.txtのc%dの仕様

ユーザ定義図形

 jwrディレクトリ内のshape_ex.rbというファイルに、三角形と矩形を定義しています。以下は、3つの指示点から三角形を作り描画する処理です。

p1 = jw[1]
p2 = jw[2]
p3 = jw[3]
triangle = Triangle.new(p1, p2, p3)
jw.draw(triangle)

線と線の交点に点を置く

line1, line2 = jw.shapes
x, y = line1.intersection(line2)
jw.point(x, y)

出力先を変える

#! ruby -Ks
require "jwr"

Jwr.start(:output => "output.txt"){|jw|
  # 処理結果はoutput.txtに保存され、外部変形は実行されない
}