==================================================発行部数1004=====
     AutoCADカスタマイズ入門講座              No.27 1999/12/05
===================================================================
 AutoCADカスタマイズ入門講座をご購読頂きありがとうございますm(__)m。
今回号で、読者数が4桁の大台を突破しました。世の中にはは数千、数万の
読者数を誇るメールマガジンも珍しくはありませんが、AutoLISPというマイ
ナーな話題で1000人以上の方に購読して頂いているというのは、僕個人とし
ては当初考えもしなかった事でしす。
 今回で27号となりましたが、書き始める前まではもっと上手に解説できる
のではないかと思っていたのですが、正直な所すぐ甘い考えである事が分か
りました^^;)。うまく書く事が出来ません。毎回発行後に読み返してみると
トホホと思う事ばかりです。その様な訳で本当に皆さんありがとうございま
す。

--------------------------------------------------------------------
 1.申し訳ございません
--------------------------------------------------------------------
 さて、前回号(26号)の3.で、点が直線上にあるかどうかの判定を行うプ
ログラムを解説したのですが、読み返してみるとちょっと変というか、この
プログラムでは説明している様な判定を行う事は出来ません。ちょっと、と
いうかいっぱい勘違いしていたようです。やっぱり、夜中に急いで考えたり
するとろくな事はありませんね。申し訳ございませんが、この部分からもう
一度スタートします。

--------------------------------------------------------------------
 2.点が直線上にあるかどうかの判定
--------------------------------------------------------------------
 今回は前回よりもっと簡単な判別方法を使用します。つまり、2直線の始
点、終点のx座標(y座標でも構いません)の大小を比較して、それぞれの端点
が片方の直線上にあるかどうかを判別します。ここで注意しなければならな
い事は、例えばこの判定をx座標で行った場合には、y軸に平行な直線の重
なり具合の判定は出来ない事です。逆にy座標で判定を行った場合には、x軸
に平行な直線の判定は行えません。ですので、今回の方法を使用した場合に
は、x軸またはy軸に平行な直線用に特別の処理を加える必要があります(今
回のプロトタイプでは加えていません。最終的なプログラムには加えます)。
 プログラムを見て頂けば分かるように、今回はそれぞれの直線のx座標を
使用して2直線の重なりを判定しています。プログラム自体は簡単なので、
見て頂ければ内容はすぐ分かると思います。if文で4つの条件を比較してい
ますが、チェック用の変数(ck1〜4)が0のままの所の点をマージ後の直線に
使用します。実際に重なった直線を作成し、プログラムの出力するメッセー
ジを確認してみて下さい。

--------------------------------------------------------------------
 3.merge.lsp(改定版2)
--------------------------------------------------------------------
 最後に今回修正したプログラムを添付します。次回は2つの直線を1つに置
き換える部分を考えていきたいと思います。
また、merge.lspは殆どテストをしていないので不具合があると思います。
不具合がありましたらお知らせ頂けたら幸いです。
それでは、次号をお楽しみに。

(defun C:merge()
  ; 2つのエンティティを選択
  (setq name1 (car (entsel "最初の直線を選択して下さい:")))
  (setq name2 (car (entsel "2本目の直線を選択して下さい:")))

  ; 2直線の始点、終点を得る
  (setq p10 (cdr (getprop name1 10)))
  (setq p11 (cdr (getprop name1 11)))
  (setq p20 (cdr (getprop name2 10)))
  (setq p21 (cdr (getprop name2 11)))

  ; 2直線の作図角度を得る
  (setq ang1 (angle p10 p11))
  (setq ang2 (angle p20 p21))

  ; 求めた2直線の作図角度を補正する
  ; 作図角度 < π
  (setq ang1 (mangle ang1))
  (setq ang2 (mangle ang2))

  (setq eps 1e-3)   ; 許容値
  
  ; 作図角度の判定
  (if ( < (abs (- ang1 ang2)) eps)
    (progn
    (print "作図角度は同一です")
    ; 2直線に直行する直線の準備
    ; 始点p10、終点p30の直線を設定する
    (setq p30 (polar p10 (+ ang1 (/ pi 2.0)) 1.0))

    ; 2直線と垂線の交点を求める
    (setq intp1 (inters p10 p11 p10 p30 nil))
    (setq intp2 (inters p20 p21 p10 p30 nil))

    ; 交点間の距離を求め、許容値以下か判定
    (if (< (distance intp1 intp2) eps)
      (progn
        (print "直線間の距離は許容値以下です")
        ; チェック用変数を初期化
        (setq ck1 0)
        (setq ck2 0)
        (setq ck3 0)
        (setq ck4 0)
        ; 直線1のx座標の範囲を求める
        (if (< (car p10) (car p11))
           (progn
              (setq max1 (car p11))
              (setq min1 (car p10))
           )
           (progn
              (setq max1 (car p10))
              (serq min1 (car p11))
           )
       )
       ; 直線2のx座標の範囲を求める
        (if (< (car p20) (car p21))
           (progn
              (setq max2 (car p21))
              (setq min2 (car p20))
           )
           (progn
              (setq max2 (car p20))
              (serq min2 (car p21))
           )
       )

       ; 直線1のx座標の範囲に、直線2の始点、終点のx座標が
       ; 入るかどうかをチェックする
       (if (and (< min1 min2) (< min2 max1))
          (progn
             (setq ck1 1)
             (print "min2はマージ後の直線に使われません")
          )
          (print "min2をマージ後の直線に使用します")
       )
       (if (and (< min1 max2) (< max2 max1))
          (progn
             (setq ck2 1)
             (print "max2はマージ後の直線に使われません")
          )
          (print "max2をマージ後の直線に使用します")
       )
       ; 直線2のx座標の範囲に、直線1の始点、終点のx座標が
       ; 入るかどうかをチェックする
       (if (and (< min2 min1) (< min1 max2))
          (progn
             (setq ck3 1)
             (print "min1はマージ後の直線に使われません")
          )
          (print "min1をマージ後の直線に使用します")
       )
       (if (and (< min2 max1) (< max1 max2))
          (progn
             (setq ck4 1)
             (print "max1はマージ後の直線に使われません")
          )
          (print "max1をマージ後の直線に使用します")
       )



      )
    )
    )
  )
  (terpri)
)

;---------------------------
; 属性取得関数
;---------------------------
(defun getprop(entname grpcode / elist)
  (setq elist (entget entname))
  (assoc grpcode elist)
)

;------------------------------------------
; π以上の角度をπ以下の角度に補正する関数
;------------------------------------------
(defun mangle(angle / i)
  (setq i 0)
  (while (= i 0)
    (if (> angle pi)
      (setq angle (- angle pi))
      (setq i 1)
    )
  )
  (setq angle angle)
)


●バックナンバーは下記のURLで参照する事が出来ます。
http://www2u.biglobe.ne.jp/~Saturn5/alisp.htm
====================================================================
■登録/解除の方法
http://www2u.biglobe.ne.jp/~Saturn5/alisp.htm
「AutoCADカスタマイズ入門講座」は、上記URLよりいつでも
登録/解除可能です。
====================================================================
●広告の問い合わせ
広告のお問い合わせは以下のメールアドレスへお願いします。
wankichi@mba.nifty.ne.jp
====================================================================
■「AutoCADカスタマイズ入門講座」No.26
発行責任者 :わんきち(wankichi@mba.nifty.ne.jp)
発行システム:インターネットの本屋さん『まぐまぐ』
              http://www.mag2.com/
              マガジンID:0000011579
====================================================================