Đến nội dung


Hình ảnh
* * * * * 1 Bình chọn

[Yêu cầu] Lisp đo và điền giá trị diện tích


  • Please log in to reply
10 replies to this topic

#1 bachngoctung

bachngoctung

    biết lệnh copy

  • Members
  • PipPipPip
  • 115 Bài viết
Điểm đánh giá: 11 (tàm tạm)

Đã gửi 21 September 2011 - 06:35 PM

- Xin chào cả nhà hôm này mình lại có một việc rất cần đến sự giúp đỡ của các bạn. Mình cần đo diện tích và đánh số thứ tự cho từng lô đất, nội dung lisp mình xin trình bày cụ thể như sau:

- Mình đã làm sẵn một block thuộc tính có tên là KHLODAT, trong block có hai thuộc tính là DT(diện tích), LODAT(tên và số thứ tự lô đất).

- Ví dụ LK-09:01 được hiểu như sau:

+ LK-09: tên lô đất (cái này được khai báo ban đầu và được cố định trong suốt quá trình thực hiện lệnh)

+ 01: số thứ tự lô đất (được khai báo số bắt đầu khi thực hiện lệnh và sẽ tự cộng thêm 1 sau mỗi lần diện tích của một lô đất được đo)

- Cấu trúc lisp:

+Đánh lệnh clo:

+ Số thứ Tự <01>/Tên Lô đất<LK-09>/<Chỉ điểm>:

+ Sau khi khai báo ban đầu và chỉ điểm vào vùng cần đo diện tích, diện tích đã được nhớ và lisp sẽ hỏi hai lựa chọn như sau: Chỉ điểm/ Chọn đường Thẳng

- Nếu ta chọn C thì sẻ chỉ 2 điểm : block sẽ được điền ra nằm trên đường thẳng đi qua hai điểm vừa chỉ.

- Mặc định là chọn T: chọn đường thẳng và block sẽ được điền ra nằm trên đường thẳng vừa chọn.

- Tường tự như vậy mỗi lần đo thì số thứ tự của lô đất sẽ dc cộng thêm 1.

LK-09:01

LK-09:02

……..

- Mình có gửi kèm theo bản cad và file lisp có code tượng tự như ý lisp trên, lệnh là tdo lisp sẽ hỏi tên mốc ban đầu và sẽ tự cộng thêm một vào tên mốc sau mỗi lần cắm mốc

- Mong cả nhà giúp đỡ, chân thành cám ơn!!!!!

Link tải file: http://www.cadviet.c...3/cadviet_1.rar

Ảnh Minh Họa

Hình đã gửi


  • 0

#2 bachngoctung

bachngoctung

    biết lệnh copy

  • Members
  • PipPipPip
  • 115 Bài viết
Điểm đánh giá: 11 (tàm tạm)

Đã gửi 22 September 2011 - 08:23 AM

Cả nhà nghiên cứu giúp mình nhé! :wacko:
  • 0

#3 lp_hai

lp_hai

    biết lệnh measure

  • Members
  • PipPipPipPipPipPip
  • 456 Bài viết
Điểm đánh giá: 202 (khá)

Đã gửi 22 September 2011 - 10:27 AM

Bạn thử xem nhá!
Tuy nhiên mình làm hơi khác yêu cầu của bạn một tý. Nguyên lý hoạt động là:
1.Chọn Block mẫu, vì block bạn có thể thay đổi khi thì LK-09: khi thì LK-10: .... vì vậy phải chọn.
2.pick diểm trong vùng tính dt, cái này ko phải nói
3.chọn điểm gốc đặt block, và chọn thêm một điểm để xác định góc quay. Nếu làm như bạn yêu cầu thì phải thêm tùy chọn C hoặ T thì cũng mất thời gian hơn là mặc định chọn 2 điểm.

(defun c:clo(/ bm bn tenlo tengoc stt st p1 p2 pt ang area po)
(setq bm (entsel "\nchon Block mau:")
bn (cdr (assoc 2 (entget(car bm))))
Tenlo (cdr (assoc 1 (entget(entnext(entnext(car bm))))))
po (vl-string-position (ascii ":") tenlo)
tengoc (substr tenlo 1 (+ po 1))
stt (getint "\nso lo dat bat dau:")
)
;;;;;;;;;;;
(while (setq pt (getpoint "\npick diem:"))
(setq p1 (getpoint "\nChon diem dat Block:")
p2 (getpoint p1 "\nChon diem 2:")
ang (/(*(angle p1 p2)180)pi)
)
(command "-BOUNDARY" pt "")
(setq area (vlax-curve-getArea (entlast)))
(setq st (if (< stt 10) (strcat "0" (rtos stt)) (rtos stt)))
(entdel(entlast))
(command "insert" bn p1 "1" "" (+ ang 90) (rtos area 2 1) (strcat tengoc st))
(setq stt (+ stt 1))
)
(princ)
)

  • 2
Hình đã gửi

#4 bachngoctung

bachngoctung

    biết lệnh copy

  • Members
  • PipPipPip
  • 115 Bài viết
Điểm đánh giá: 11 (tàm tạm)

Đã gửi 22 September 2011 - 04:14 PM

-Cám ơn bạn nhé, nhưng lisp mình chưa sử dụng được bị lỗi ; error: Function cancelled. Mong bạn xem lại giúp mình. Chân thành cám ơn.
  • 0

#5 lp_hai

lp_hai

    biết lệnh measure

  • Members
  • PipPipPipPipPipPip
  • 456 Bài viết
Điểm đánh giá: 202 (khá)

Đã gửi 22 September 2011 - 05:12 PM

-Cám ơn bạn nhé, nhưng lisp mình chưa sử dụng được bị lỗi ; error: Function cancelled. Mong bạn xem lại giúp mình. Chân thành cám ơn.

ssr ban! đã sửa lại rồi đó!
  • 1
Hình đã gửi

#6 bachngoctung

bachngoctung

    biết lệnh copy

  • Members
  • PipPipPip
  • 115 Bài viết
Điểm đánh giá: 11 (tàm tạm)

Đã gửi 22 September 2011 - 05:46 PM

ssr ban! đã sửa lại rồi đó!

- Tuyệt vời !!! cám ơn bạn rất nhiều, trong quá trình dùng có vấn đề mong bạn tiếp tục giúp đỡ.
  • 0

#7 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 22 September 2011 - 06:18 PM

Bạn thử xem nhá!
Tuy nhiên mình làm hơi khác yêu cầu của bạn một tý. Nguyên lý hoạt động là:
1.Chọn Block mẫu, vì block bạn có thể thay đổi khi thì LK-09: khi thì LK-10: .... vì vậy phải chọn.
2.pick diểm trong vùng tính dt, cái này ko phải nói
3.chọn điểm gốc đặt block, và chọn thêm một điểm để xác định góc quay. Nếu làm như bạn yêu cầu thì phải thêm tùy chọn C hoặ T thì cũng mất thời gian hơn là mặc định chọn 2 điểm.

Bước 3 chèn Block lp_hai có thể sử dụng cách này :
Sử dụng hàm (setq curve (nentselp (setq pt (getpoint "\nDiem / Duong thang Insert Block :"))))
- Nếu curve trả về Nil, tức là điểm user chọn không có đối tượng nào -> Yêu cầu chọn thêm 1 điểm nữa giống lp_hai đã làm
- Nếu curve trả về khác Nil, tức là có ename và điểm chọn
Lúc này ta có góc của vertex curve chọn + điểm chèn => làm tiếp như trường hợp 1
Lấy góc của vertex curve (*Line) tại điểm chọn, lp_hai tham khảo ở 1 lisp gần đây nhất :
http://www.cadviet.c...ndpost&p=169583
Như vậy thao tác của user vừa nhanh, lại vừa bao gồm cả 2 trường hợp :)
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#8 lp_hai

lp_hai

    biết lệnh measure

  • Members
  • PipPipPipPipPipPip
  • 456 Bài viết
Điểm đánh giá: 202 (khá)

Đã gửi 23 September 2011 - 10:31 AM

Bước 3 chèn Block lp_hai có thể sử dụng cách này :
Sử dụng hàm (setq curve (nentselp (setq pt (getpoint "\nDiem / Duong thang Insert Block :"))))
- Nếu curve trả về Nil, tức là điểm user chọn không có đối tượng nào -> Yêu cầu chọn thêm 1 điểm nữa giống lp_hai đã làm
- Nếu curve trả về khác Nil, tức là có ename và điểm chọn
Lúc này ta có góc của vertex curve chọn + điểm chèn => làm tiếp như trường hợp 1
Lấy góc của vertex curve (*Line) tại điểm chọn, lp_hai tham khảo ở 1 lisp gần đây nhất :

Đầu tiên em xin cảm ơn bác!
Nói chung em chỉ biết những code đơn giản thôi. hhehhe, hơi gà! Vì thế em cũng rất mong dc học hỏi nhiều ở các bác.
Theo hướng dẫn của bác thì em sửa lại là thêm cái hàm con : curve-no-nil vì mổi lần xài đoạn code:
(setq p1 (vlax-safearray->list p1)
p2 (vlax-safearray->list p2))
đòi hỏi p1 và p2 phải được giải phóng, có đúng vậy ko bác?
và thấy lisp chạy như sau:
1)Lisp áp dụng tốt khi chọn 2 điểm(tức là curve = nil)
2)Lisp áp dụng tốt khi Curve là line (vì chỉ có 2 đầu nên xác định góc theo phương của đường thẳng)
3)Nếu chọn điểm thứ nhất nằm trên một curve nào đó thì mặc định góc quay theo trường hợp 2(cái này hơi ép User!!?)
4)khi curve là PL có nhiều đỉnh thì nó lại xác định góc theo 2 điểm đầu và cuối nên đôi khi không đúng góc yêu cầu
Rất mong bác chỉ giáo để em tiến bộ :)


(defun c:clo (/ bm bn tenlo tengoc stt st p1 p2 pt ang area po os curve)
(setq bm (entsel "\nchon Block mau:")
bn (cdr (assoc 2 (entget (car bm))))
Tenlo (cdr (assoc 1 (entget (entnext (entnext (car bm))))))
po (vl-string-position (ascii ":") tenlo)
tengoc (substr tenlo 1 (+ po 1))
stt (getint "\nso lo dat bat dau:")
OS (getvar "osmode")
)
;;;;;;;;;;;
(while (setq pt (getpoint "\npick diem:"))
(setvar "osmode" 512)
(setq curve (nentselp (setq p1 (getpoint "\nChon diem dat Block /Duong thang Insert Block:"))))
(setvar "osmode" OS)
(if (= curve nil)
(setq p2 (getpoint p1 "\nChon diem 2:")
ang (/ (* (angle p1 p2) 180) pi)
);curve = nil
(setq ang (/ (* (angle '(0 0 0) (vlax-curve-getFirstDeriv (car curve) (vlax-curve-getParamAtPoint (car curve) (vlax-curve-getClosestPointto (car curve) p1))))180)pi))
);kt if
;;;;;;;;;;;
(command "-BOUNDARY" pt "")
(setq area (vlax-curve-getArea (entlast)) )
(setq st (if (< stt 10)
(strcat "0" (rtos stt))
(rtos stt)
)
)
(entdel (entlast))
(setq ang (+ ang 90))
(if (> ang 180) (setq ang (- ang 180)))
(command "insert" bn p1 "1" "" ang (rtos area 2 1)(strcat tengoc st))
(setq stt (+ stt 1))
)
(princ)
)

  • 0
Hình đã gửi

#9 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 23 September 2011 - 10:59 AM

Xin lỗi lp_hai vì mình không down được file để test nên mình nói bo thế này :
Hàm (curve-no-nil) của bạn trả về góc của 2 điểm (trái dưới) (phải trên) của Bounding Box đối tượng, chứ không phải góc tiếp tuyến của curve tại điểm chọn.
Trước tiên ta có : (setq curve (nentselp (setq pt1 (getpoint "\nDiem / Duong thang Insert Block :"))))
Trường hợp Nil thì xong rồi, giờ ta bàn tới trường hợp điểm pick có *Line :
Lúc đó curve sẽ trả về list dạng : (<Entity name: 7efcd448> (567833.0 2.35934e+006 0.0)), phần tử đầu là ename của curve, phần tử 2 là điểm ta pick
=> Lấy (setq curve (car curve))
Trong ví dụ ket đưa ra bạn chú ý dòng này :

(setq ang (angle '(0 0 0) (vlax-curve-getFirstDeriv curve (vlax-curve-getParamAtPoint curve pt1))))

- (vlax-curve-getParamAtPoint curve pt1) : Xác định 'Param của curve tại Point click, chính là pt1 (mình k biết dịch sát nghĩa từ Param ^^, nôm na như cách đặt tên thứ tự vậy)
- (vlax-curve-getFirstDeriv curve param) : xác định vectơ tiếp tuyến với curve tại cái param vừa xác định
- angle '(0 0 0) (vecto tiếp tuyến) : cái này để lấy góc từ vecto theo radian
=> Hàm của bạn sẽ tương tự như này :

(defun curve-no-nil (curve pt) (angle '(0 0 0) (vlax-curve-getFirstDeriv curve (vlax-curve-getParamAtPoint curve pt))))

Và sử dụng trong lisp thì (curve-no-nil (car curve) pt1)
Bạn thử áp xụng xem có được không ^^ Vì mình không dám chắc khi chưa test ^^

P/S : mình cũng gà vậy, càng ngày càng thấy còn quá non, nên cứ tà tà mà học thêm thôi ^^ Và mình thích những người nhận ra điều đó để lắng nghe mọi lời góp ý, hơn là những người giỏi/ chưa giỏi nhưng bảo thủ ta đây :)
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#10 lp_hai

lp_hai

    biết lệnh measure

  • Members
  • PipPipPipPipPipPip
  • 456 Bài viết
Điểm đánh giá: 202 (khá)

Đã gửi 23 September 2011 - 12:33 PM

hehhehe. đúng là mở mang kiến thức.
bác rãnh thì xem lại lisp giúp em cái, chạy thì cũng ok rồi nhưng mà vướng cái chổ nó xoay theo chiều của pl bác ah!
với cho em hỏi: lúc trước em có đọc một hàm mà lấy điểm ngay tại nơi mình chọn PL luôn ấy, giống như trong lệnh Break của cad, mặt định điểm đầu tiên là điểm mà mình chọn đối tượng?
  • 0
Hình đã gửi

#11 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 23 September 2011 - 12:39 PM

Chính là điểm pt1 trong hàm nentselp mà bạn ? (cadr của list trả về)
Với entsel cũng thế. Nentsel cũng thế ^^ Kết quả bao giờ cũng là list (ename điểm_chọn). Với nentselp thì mình đã cung cấp trước điểm_chọn cho nó bằng hàm getpoint.
Với góc xoay chèn Blocks, có khả năng bạn gặp trường hợp block lộn lại ^^
=> Nghiên cứu hàm này

(defun LM:MakeReadable ( a )<pre> ;; © Lee Mac 2010 (cond ( (and (> a (/ pi 2)) (<= a pi)) (- a pi) ) ( (and (> a pi) (<= a (/ (* 3 pi) 2))) (+ a pi) ) ( a ) ) </pre>
)


  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC