วันอาทิตย์ที่ 24 ตุลาคม พ.ศ. 2553

AutoCAD Tips: Visual LISP ( AutoLISP ) เรื่องของการแบ่งครึ่ง

ตำแหน่งกึ่งกลางบนเส้นตรง
เป็นที่ทราบกันดีว่าใช้ Object snap ที่ Midpoint

ตำแหน่งกึ่งกลางระหว่าง 2 จุด หาได้อย่างไร
พิมพ์ MTP หรือ M2P ในพรอมต์ถามจุด และคลิกเลือก 2 จุด จะได้การวางตำแหน่งที่จุดกึ่งกลางระหว่าง 2 จุดที่เลือก เช่น มีเส้นตรงหรือเส้นโค้งที่เป็นคู่ขนานกันอยู่ จะสร้างเส้นระหว่างกลาง ให้ใช้คำสั่ง OFFSET ตัวเลือก Through เลือกเส้นต้นฉบับที่มีอยู่เส้นใดเส้นหนึ่ง พิมพ์ M2P กด Enter จับจุดด้วย Osnap | Nearest บนเส้นแรก และจับจุดด้วย Osnap | Perpendicular บนเส้นที่สอง

หรือจะประยุกต์ใช้ MTP/M2P กับการวาดรูเจาะระหว่างกึ่งกลางรูเจาะสองรูที่มีอยู่ก่อนแล้ว ก็จะเป็นไปในทำนองเดียวกัน โดยใช้คำสั่ง Circle ที่พรอมต์ถามจุดศูนย์กลาง พิมพ์ M2P กด Enter แล้วคลิกเลือกจุดศูนย์กลางของวงกลมที่มีอยู่แล้ว โดยจับจุดด้วย Osnap | Center ตามด้วยการป้อนค่ารัศมีหรือเส้นผ่านศูนย์กลาง

แบ่งครึ่งมุม
ขณะที่เรื่องของการแบ่งครึ่งบนเส้นตรงหรือระหว่างสองจุดใดๆจะถูกกล่าวถึงค่อนข้างแพร่หลาย แต่ถ้าเป็นการแบ่งครึ่งมุม (Angle Bisect) จะมีคำตอบให้หรือไม่?


จริงๆแล้วใน AutoCAD มีคำสั่งจัดการเรื่องแบ่งครึ่งมุมให้โดยตรงอยู่แล้ว นั่นคือ XLINE ที่ตัวเลือก Bisect นั่นเอง มีพรอมต์ตามรูปนี้


กล่าวคือ ให้กำหนดจุดยอดมุม (vertex) ตามด้วยจุดบนแขนเส้นตรงสองเส้น เพียงเท่านี้ก็จะได้เส้นที่มีความยาวเป็นอนันต์ (infinity) ของ XLINE แล้ว และยังคงให้เลือกมุมอื่นๆได้อีก จนกว่าจะกด Enter เพื่อจบคำสั่งนี้
เคล็ดลับ กรณีเส้นไม่บรรจบกันเป็นมุม
ให้เปิดใช้ AutoSnap ที่ตัวเลือก Extension เอาไว้ แล้วลากแนวออกมาจากเส้นทั้งสอง จะได้จุดตัดกันเป็นจุดยอดมุม (vertex)


ปิดท้ายบทความนี้ ด้วยเครื่องมือทุ่นแรง อีกสักนิด
นั่นคือโค้ด LISP สำหรับหาเส้นแบ่งครึ่งมุม โดยใช้ได้กับเส้นตรง (LINE) และเส้นโพลีไลน์ (POLYLINE)

มีพรอมต์เป็น

Command: พิมพ์ b กด Enter
Developed by schatchawal@gmail.com
Select first line (near the corner): คลิกเส้นแรกที่ใกล้มุม
Select second line: คลิกเส้นที่สอง

เพียงเท่านี้ คำสั่ง b หรือ abisect นี้ก็จะวาดเส้นแบ่งครึ่งมุมให้


เส้นแบ่งครึ่งมุมนี้มีความยาวเท่ากับเส้นแรกที่ถูกเลือก

ส่วนโค้ดมีดังนี้

;;; Angle Bisector
(defun c:b () (c:abisect) (princ))
;; (1select "\nSelect first line (near the corner): "
;; (list "AcDbLine" "AcDbPolyline")
;; "\nMust be LINE or LWPOLYLINE!!!")
(defun 1select (msg obj_type_list err_msg / e1 obj1 stop)
(while (not stop)
(if (setq e1 (entsel msg))
(progn
(setq obj1 (vlax-ename->vla-object (car e1)))
(if (member (vla-get-ObjectName obj1)
obj_type_list
)
(setq stop T)
(princ err_msg)
)
)
(princ "\nNo object found!!!")
)
)
e1
)
;; 1vector of P to Q point.
(defun 1vectorPQ (P Q / u d)
(if (not (zerop (setq d (distance P Q))))
(mapcar '(lambda (x)
(/ x d)
)
(mapcar '- Q P)
)
nil
)
)
;;Main version
(defun c:abisect (/ e1 e2 obj1 p11 p12 p21
p22 ip mp objType1 1u 1v
w 1w d param d1 d2 LL
*acaddoc* *mspace* *error*
)
(vl-load-com)
(princ "\nDeveloped by schatchawal@gmail.com")
(setq *acaddoc* (vla-get-activedocument (vlax-get-acad-object))
*mspace* (vla-get-modelspace *acaddoc*)
)
(defun *error* (msg)
(if (not (member msg (list "Function cancelled")))
(princ (strcat "\nBISECT Error: " msg))
)
(vla-endundomark *acaddoc*)
(princ)
)
(vla-startundomark *acaddoc*)
(setq e1
(1select "\nSelect first line (near the corner): "
(list "AcDbLine" "AcDbPolyline")
"\nMust be LINE or LWPOLYLINE!!!"
)
e2
(1select "\nSelect second line: "
(list "AcDbLine" "AcDbPolyline")
"\nMust be LINE or LWPOLYLINE!!!"
)
p11 (osnap (cadr e1) "Nearest")
p12 (osnap (cadr e1) "End")
p21 (osnap (cadr e2) "Nearest")
p22 (osnap (cadr e2) "End")
obj1 (vlax-ename->vla-object (car e1))
objType1 (vla-get-objectName obj1)
)
(if (setq ip (inters p11 p12 p21 p22 nil))
(progn
(cond
((equal objType1 "AcDbLine")
(setq LL (vla-get-Length obj1))
)
((equal objType1 "AcDbPolyline")
(setq
param
(fix (vlax-curve-getParamAtPoint
obj1
(vlax-curve-getClosestpointTo obj1 (trans p11 1 0))
)
)
D1
(vlax-curve-getDistAtParam obj1 param)
D2
(vlax-curve-getDistAtParam obj1 (1+ param))
LL
(abs (- D2 D1))
)
)
) ;cond
;; Find MP with plus 2 vectors
(if (and (setq 1u (1vectorPQ (trans ip 1 0) (trans p11 1 0)))
(setq 1v (1vectorPQ (trans ip 1 0) (trans p21 1 0)))
)
(progn
(setq
w (mapcar '+ 1u 1v)
d (sqrt (apply '+ (mapcar '* w w)))
1w (mapcar '/ (mapcar '/ w (list d d d)))
mp (mapcar '+
(trans ip 1 0)
(mapcar '* 1w (list LL LL LL))
)
)
;; Draw Bi-sect Line
(vla-addLine
*mspace*
(vlax-3d-point (trans ip 1 0))
(vlax-3d-point mp)
)
)
(princ "\nCannot process!!!")
)
)
(princ "\nNo intersection!!!")
)
(vla-endundomark *acaddoc*)
(princ)
)

********************************************
ส่วนการแบ่งพื้นที่ให้รูปทรงใดๆแม้ว่าจะเป็น Irregular shape อะไรก็ตาม
ลองใช้คำสั่ง DIVA จากหัวข้อนี้
http://chatchawalsupakasem.blogspot.com/2010/06/visual-lisp-autocad-tips.html
http://chatchawalsupakasem.blogspot.com/2010/06/visual-lisp-autocad-tips-diva.html

ไม่มีความคิดเห็น:

แสดงความคิดเห็น