変換マトリクス



UCSが設定してある図面において、
赤い線をLISPでブロックにすることを考える。
まずは普通にentgetしてブロックにし、insertしてみる。

(defun c:test(/ E_DATA)
;;線のエンティティデータE_DATA
(setq E_DATA (entget (car (entsel "\n線を選択:"))))
;;ブロック名B_NAME
(setq B_NAME "テストォ")
(entmake
(list
'(0 . "BLOCK")
'(100 . "AcDbEntity")
'(67 . 0)
(cons 8 (getvar "clayer"))
'(100 . "AcDbBlockBegin")
'(70 . 2)
'(10 0.0 0.0 0.0)
(cons 2 B_NAME)
'(1 . "")
)
)
;;属性
(entmake E_DATA)
;;ブロック宣言終わり
(entmake
(list
'(0 . "ENDBLK")
(cons 8 (getvar "clayer"))
)
)
)

すると、あ~ら不思議、UCSが設定されてるので、とんでもない傾きに。

つまり、WCSでの傾きを求めなければならない。

こんな点の変換を行う必要がある・・・ってどうすればいいんじゃ!
いや~な予感がしつつ、マトリクス変換とかいうのを使わにゃ面倒だ。
ってかマトリクス変換って方が面倒に感じる私だが、がんばるしかない。

(defun y_ucsrotate(
PT	;座標
B_PT	;挿入点
/
)
(y_pt+ (y_matrix (y_pt- PT B_PT) (y_ucsmatrix)) B_PT)
)
(defun y_matrix(
PT	;座標
MT	;変換マトリクス
/
)
(mapcar
'(lambda (x)
(+
(* (nth x (nth 0 MT))(nth 0 PT))
(* (nth x (nth 1 MT))(nth 1 PT))
(if (= (length PT) 3)
(* (nth x (nth 2 MT))(nth 2 PT))
0.0
)
(nth x (nth 3 MT))
)
)
(if (= (length PT) 3)
'(0 1 2)
'(0 1)
)
)
)
(defun y_ucsmatrix(
/
)
(list
(trans '(1 0 0) 0 1 T)
(trans '(0 1 0) 0 1 T)
(trans '(0 0 1) 0 1 T)
'(0 0 0)
)
)

UCSは設定したままでね。
(y_ucsrotate 変換したい座標 ブロックの原点)
これで変換先のWCSの座標が求められる(はず)。
試しに、
(command “circle” (trans (y_ucsrotate (trans (getpoint) 1 0) (trans (getpoint) 1 0)) 0 1) “500”)
とかしてみると、変換されてるのがわかる。
誰か行列教えてくれ~。

  1. #1 by mkr - 2月 21st, 2005 at 03:29

    こちらでは、はじめまして
    行列ではないけど、下記の方法もありかなと・・・(^ ^;
    円やTEXT等、DXFデータがOCS座標の場合もありますけど、
    DXF-210を使った trans 関数変換でいけると思います。
    (defun c:test(/ E_DATA B_NAME wcs->ucs test-wcs->ucs)
    ;; 点を WCS座標からUCS座標に変換
    (defun wcs->ucs (p) (trans p 0 1))
    ;; 線分図形データのWCS座標定義点を現在のUCS座標に変換
    (defun test-wcs->ucs (gpl edl / gpc)
    (repeat (length gpl)
    (setq
    gpc (car gpl)
    edl (subst (cons gpc (wcs->ucs (cdr (assoc gpc edl)))) (assoc gpc edl) edl)
    gpl (cdr gpl)
    );setq
    );repeat
    edl
    );;defun
    ;;; メインルーチン
    ;; 線のエンティティデータE_DATA
    (setq E_DATA (entget (car (entsel “\n線分を選択: “))))
    ;; DXF-10,11 をUCS座標に変換
    (setq E_DATA (test-wcs->ucs (list 10 11) E_DATA))
    ;; ブロック名B_NAME
    ;; (setq B_NAME “テストォ”)
    (setq B_NAME “テストォ__”)
    (entmake
    (list
    ‘(0 . “BLOCK”)
    ‘(100 . “AcDbEntity”)
    ‘(67 . 0)
    (cons 8 (getvar “clayer”))
    ‘(100 . “AcDbBlockBegin”)
    ‘(70 . 2)
    ‘(10 0.0 0.0 0.0)
    (cons 2 B_NAME)
    ‘(1 . “”)
    )
    )
    ;; 属性
    (entmake E_DATA)
    ;; ブロック宣言終わり
    (entmake
    (list
    ‘(0 . “ENDBLK”)
    (cons 8 (getvar “clayer”))
    )
    )
    );;END DEFUN

  2. #2 by ゆり - 2月 21st, 2005 at 12:03

    間違えて一瞬消してしまいました。
    復活してよかった(^^;
    DXF210って押し出し方向だよね??
    どこで使ってるんだろう・・・。
    私には理解できない(TT)
    帰ったらがんばってみます。

  3. #3 by liki - 2月 21st, 2005 at 22:42

    http://www1.harenet.ne.jp/~hanafusa/mt/memo/archives/000094.html
    これかな。
    手元には昔のhanafusa氏の資料がある。で、これ勝手にLISPLib.lspに入れちゃってる。
    zviewport.lspなんかはマトリックスと(trans)使ってごちょごちょと。

  4. #4 by ゆり - 2月 22nd, 2005 at 08:32

    読んでもわからないぜ・・・(TT)
    私の方法が合ってたのかどうかもわからん。
    mkrさんの試したいけど、家帰るとお子様の遊べ攻撃で、
    試せない~(TT)

  5. #5 by mkr - 2月 22nd, 2005 at 14:29

    3D回転した図形
    押出し方向は変換しなくても大丈夫かなぁ~と思っていたら、
    やっぱりでした。(_ _;;
    DXF-210=押出し方向(ベクトル)も変換してやらないと
    ブロック登録コマンドで定義したのと全く同じにはならないですね。

(will not be published)

  1. No trackbacks yet.