Đến nội dung


Hình ảnh
* * * - - 17 Bình chọn

Hỏi về Lisp (thuật toán, ý tưởng, coding,...)


  • Please log in to reply
2854 replies to this topic

#1181 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 15 June 2012 - 02:04 PM

Khi mình select 1 viewport clip thì hộp thoại properties hiện rõ ràng thông tin đối tượng là viewport. nhưng khi chọn (car (entget)) thì nó lại trả về ename của polyline dùng để clip viewport đó. Các bác xem có cách nào lấy được thông tin custom scale của 1 viewport bất kể nó có bị clip hay không giúp mình phát.
  • 0

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#1182 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 15 June 2012 - 03:32 PM


(defun gcsc (en / ve vl eData)
(setq eData (entget en) ve vlax-ename->vla-object)
(cond ((= (cdadr eData) "VIEWPORT")(setq vl (vla-get-customscale (ve en))))
(T
(cond ((assoc 330 eData)
(foreach x eData
(if (and (eq 330 (car x))(= (cdadr (entget (cdr x))) "VIEWPORT"))
(setq vl (vla-get-customscale (ve (cdr x))))
)
))
)
)
)
vl
)

  • 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


#1183 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 22 June 2012 - 07:31 PM

Hôm nay mình có 2 vấn đề muốn hỏi, kg biết đã có hay chưa, nếu có rồi mong các bạn chỉ điểm cho.
1/- Trong Lisp để tạo biến dạng List ta phải viết (setq lst (append lst (list data))). Đó là hàm Lisp thuần tuý, kg biết sau này có hàm nào tạo list nhanh hơn xin các bạn chỉ cho.
2/- Giả sử có lst (("1" ( 1 2 0)) ("2" ( 2 3 0)) ....). có nghĩa ta có một list khá lớn mà mỗi phần tử có hai phần tử con. Để tìm một phần tử nào đó theo phần tử con thứ nhất ta hay dùng hàm assoc. VD (assoc "2" lst) -> ("2" (2 3 0)). Bây giờ muốn tìm theo đối số là phần tử thứ hai thì làm thế nào.
- Có hàm nào của Lisp làm việc này chưa, nếu có các bạn chỉ giúp mình
- Nếu chưa có thì viết nó thể nào để chạy cho nhanh, việc duyệt qua list rồi so sánh thì dễ nhưng chậm. Mình nghĩ có thể viết hàm dệ qui cho nó trả về một list mà mỗi phần tử đã đc đảo ngược (tránh việc nhớ lại biến làm nó chậm), sau đó lại dùng assoc với đối số là phần tử thứ 2. (Mỗi list của mình độ dài khoảng 250 (nhưng có hàng ngàn cái như vậy) nên viết đệ qui chắc kg ảnh hưởng gì)
Mong các bạn để mắt tới và viết giúp, cái khoảng đệ qui mình tịt. Xin cám ơn
  • 0

#1184 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 22 June 2012 - 08:22 PM

1/ Em chưa biết bác tổ chức dữ liệu danh sách kiểu gì, dùng nó sau đó như thế nào nên cũng khó trả lời câu hỏi này. Với visual lisp ta có 2 kiểu tổ chức dữ liệu khác dạng mảng là VARIANTS và SAFEARRAYS có thể dùng thay thế list. Em không chắc tốc độ việc truy cập dữ liệu của nó có nhanh hơn LIST hay không nhưng cấu trúc của nó quy định rất chặt chẽ và tương đối phức tạp để tạo.

2/ Đệ quy không nhanh hơn các phương pháp lặp khác đâu bác ạ. thậm chí có thể chậm hơn. với phương pháp này, máy tính sẽ phải cấp phát bộ nhớ để lưu kết quả trả về của mỗi lần lặp cho đến khi vòng lặp tìm được điều kiện thoát mới giải phóng bộ nhớ hoàn toàn.
1 ví dụ đơn giản để bác có thể tiếp cận và hiểu đệ quy, quay lui là như thế nào, đây là hàm tính n! (defun n! (n) (if (= n 1) 1 (* n (n! (1- n)))))
Về yêu cầu của bác thì em nghĩ có thể giải quyết đơn giản nhất như sau: (assoc gia_tri_tim_kiem (mapcar 'reverse list_tim_kiem ))
  • 1

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#1185 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 22 June 2012 - 09:46 PM

1. (setq lst (list data)) thôi chứ bác nhỉ :)
2. (car (vl-member-if ...))
  • 2

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


#1186 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 22 June 2012 - 11:31 PM

Cám ơn bác Thai và Ketxu. Câu 2 làm như bác Thái hướng dẫn đc rồi, vậy mà hồi nào giờ mình kg biết. Còn câu 1 việc sd array mình chưa quen và có lẽ nó ít đc hỗ trợ hơn list, có lẽ dùng list đã, tính sau.

Bây giờ mình lại hỏi tiếp. Mình tính đưa một danh sách lên khung đối thoại có sd bảng như excel. nếu viết trong arx thì có cách gọi theo vc, nhưng viết trong Lisp thì gọi DLL như thế nào. VD :
- file dll là : vidu.dll
- Giả sử một hàm có trong dll là : ShowForm(Pchar noidung, int i, double k) thì gọi trong Lisp thế nào.
Mong được các bác hướng dẫn.
  • 0

#1187 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 23 June 2012 - 01:43 AM

1. Trong trường hợp này mọi cách đảo ngược đều chậm hơn duyệt phần tử.
2. Hình như nếu file dll k viết hàm kiểu Lispfuntion hoặc k thông qua trung gian thì không
  • 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


#1188 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 23 June 2012 - 05:02 PM

1. Trong trường hợp này mọi cách đảo ngược đều chậm hơn duyệt phần tử.
2. Hình như nếu file dll k viết hàm kiểu Lispfuntion hoặc k thông qua trung gian thì không

1. Mình thử TH của bác Thai hướng dẫn rồi, nói chung nó rất nhanh (có thể nhanh hơn nhiều PP duyệt qua từng phần tử)
2. Câu này bạn nói mình chưa hiểu gì hết. Bạn có thể nói rõ hơn chút. Cám ơn bạn
  • 0

#1189 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 23 June 2012 - 05:39 PM

1.(assoc sth (Mapcar 'reverse lst) ) sẽ đảo ngược từng phần tử sub-list, sau đó thực hiện hàm assoc. K kể hàm assoc thì nó đã duyệt qua từng phần tử
(car (vl-member-if sth ...)) : sẽ tìm từng phần tử, đến phần tử nào thỏa mãn hàm sth thì dừng lại, lấy toàn bộ member list từ đó trở đi. Sau đó lấy car. (while ((car lst) =/ giá_trị) (setq lst (cdr lst))) : tìm đến khi nào chưa thỏa hàm sth, dừng lại ở phần tử đó. Thú vị ở đây là hàm cdr nhanh hơn cả việc duyệt theo biến đếm

..... Tóm lại là nếu phần tử thỏa mãn ở càng gần đầu thì càng thấy sự khác biệt tốc độ ^^á
2. Cái này chờ các bác viết Autocad Net vào giải thích thui ^^
  • 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


#1190 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5454 Bài viết
Điểm đánh giá: 2626 (tuyệt vời)

Đã gửi 23 June 2012 - 05:50 PM

Góp 1 ý kiến nhỏ: trong trường hợp tổng quát thì FuncA nhanh hơn FuncB. Nhưng trong những trường hợp đặc biệt thì có thể FuncB nhanh hơn FuncA: đó là đôi lúc gặp... "may mắn". :lol:
VD: khi duyệt từng phần tử nhưng ngay phần tử đầu tiên đã thoả (nhanh) nên nó không duyệt hết tất cả các phần tử (chậm).
Ý kiến cá nhân: nên dùng cái nhanh tổng quát sẽ tốt hơn.
  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#1191 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 24 June 2012 - 04:52 AM

1.(assoc sth (Mapcar 'reverse lst) ) sẽ đảo ngược từng phần tử sub-list, sau đó thực hiện hàm assoc. K kể hàm assoc thì nó đã duyệt qua từng phần tử
(car (vl-member-if sth ...)) : sẽ tìm từng phần tử, đến phần tử nào thỏa mãn hàm sth thì dừng lại, lấy toàn bộ member list từ đó trở đi. Sau đó lấy car. (while ((car lst) =/ giá_trị) (setq lst (cdr lst))) : tìm đến khi nào chưa thỏa hàm sth, dừng lại ở phần tử đó. Thú vị ở đây là hàm cdr nhanh hơn cả việc duyệt theo biến đếm

..... Tóm lại là nếu phần tử thỏa mãn ở càng gần đầu thì càng thấy sự khác biệt tốc độ ^^á
2. Cái này chờ các bác viết Autocad Net vào giải thích thui ^^

Theo mình nghĩ những hàm thuộc hệ thống như assoc hay member ..., tức những hàm của bản thân Cad cung cấp thì nó dựa vào cơ chế tìm kiếm của danh sách có chỉ mục, tức khi ta tạo ds thì Lisp vẫn giữ thứ tự thế nhưng bên trong đã đc đưa vào dạng dữ liệu chuẩn như ta thấy trên các phần mềm csdl, các cơ chế tìm kiếm sắp xếp đều đã chuẩn nên nó nhanh hơn ta duyệt nhiều. Mình đã thử bài toán như sau :

(defun c:thu( / i L lis tg1 tg2 tg3 tg4)
(setq i 0 L 5000 lis nil)
(while (< i L)
(setq lis (append lis (list (list i (- L i)))))
(setq i (1+ i))
)
(setq start (getvar "millisecs"))
(setq i 0)
(while (< i L)
(if (member (list i (- L i)) lis) (print i))
(setq i (1+ i))
)
(setq tg1 (/ (- (getvar "millisecs") start) 1000.0))

(setq start (getvar "millisecs"))
(setq i 0)
(while (< i L)
(if (assoc i lis) (print i))
(setq i (1+ i))
)
(setq tg2 (/ (- (getvar "millisecs") start) 1000.0))
(setq start (getvar "millisecs"))
(setq i 0)
(while (< i L)
(if (assoc (- L i) (Mapcar 'reverse lis)) (print i))
(setq i (1+ i))
)
(setq tg3 (/ (- (getvar "millisecs") start) 1000.0))

(setq start (getvar "millisecs"))
(setq i 0)
(while (< i L)
(setq j 0)
(while (and (< j L) (/= (cadr (nth j lis)) (- L i))) (setq j (1+ j)))
(print i)
(setq i (1+ i))
)
(setq tg4 (/ (- (getvar "millisecs") start) 1000.0))
(print (strcat "\n Member mat " (rtos tg1 2 3) "s. Assoc mat " (rtos tg2 2 3) "s. Assoc 'Re mat " (rtos tg3 2 3) "s. Duyet mat " (rtos tg4 2 3)))
(princ)
)
Và kết quả :
"\n Member mat 3.484s. Assoc mat 1.672s. Assoc 'Re mat 11.422s. Duyet mat 210.422"
  • 0

#1192 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5454 Bài viết
Điểm đánh giá: 2626 (tuyệt vời)

Đã gửi 24 June 2012 - 12:55 PM

1). 4 kiểu đều lặp hết list nên phương pháp so sánh thời gian của bạn là hợp lý.
2). Cách xây dựng kiểu duyệt từng phần tử: ở đây bạn đã "ép duyên" việc duyệt phần tử rồi. Thêm 1 while trong while thì nó sẽ chậm là tất yếu thôi. Sau khi duyệt qua 1 phần tử và so sánh, ta phải cắt bớt list đi bằng cdr chứ.
Bạn thử thay trường hợp 4 bằng cách duyệt qua từng phần tử theo kiểu dưới đây thì sẽ thấy kết quả khác ngay.

(setq start (getvar "millisecs"))
(setq i 0)
(while (< i L)
(if (not (equal (car lis) (nth i lis)))
(progn
(setq lst (cdr lst))
(print i)))
(setq i (1+ i)))
(setq tg4 (/ (- (getvar "millisecs") start) 1000.0))

  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#1193 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 24 June 2012 - 01:08 PM

1). 4 kiểu đều lặp hết list nên phương pháp so sánh thời gian của bạn là hợp lý.
2). Cách xây dựng kiểu duyệt từng phần tử: ở đây bạn đã "ép duyên" việc duyệt phần tử rồi. Thêm 1 while trong while thì nó sẽ chậm là tất yếu thôi. Sau khi duyệt qua 1 phần tử và so sánh, ta phải cắt bớt list đi bằng cdr chứ.
Bạn thử thay trường hợp 4 bằng cách duyệt qua từng phần tử theo kiểu dưới đây thì sẽ thấy kết quả khác ngay.


(setq start (getvar "millisecs"))
(setq i 0)
(while (< i L)
(if (not (equal (car lis) (nth i lis)))
(progn
(setq lst (cdr lst))
(print i)))
(setq i (1+ i)))
(setq tg4 (/ (- (getvar "millisecs") start) 1000.0))

Do cái mục đích của mình :
- Công việc của mình luôn phải giữ các list gốc, chỉ có thể thay đổi nhưng kg làm mất đi. Có nghĩa mỗi lần mình tìm kiếm cái gì đó, nhưng kg phải tìm kiếm rõi thì thôi, lần sau có thể tìm kiếm cũng với cái đó trên list đó.VD khi bạn quản lý điểm và tìm một điểm nào đó trên bản đồ,
- Vì tránh TH phần tử gần đầu hay gần đuôi và phép thử luôn thực hiện trên list nguyên bản. Mình cho nó lặp từ đầu tới cuối là lấy thời gian chung nhất, công bằng nhất.
  • 0

#1194 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5454 Bài viết
Điểm đánh giá: 2626 (tuyệt vời)

Đã gửi 24 June 2012 - 01:13 PM

1). Nếu cần giữ list gốc thì (setq list_goc lis) rồi thực hiện các lệnh trên lis thôi.
2). Ủng hộ bạn xét đến cuối list cho cả 4 trường hợp cho... công bằng.
3). Từ ví dụ tôi đưa ra => không thể khẳng định duyệt từng phần tử là chậm.
  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#1195 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 24 June 2012 - 04:28 PM

Theo mình nghĩ những hàm thuộc hệ thống như assoc hay member ..., tức những hàm của bản thân Cad cung cấp thì nó dựa vào cơ chế tìm kiếm của danh sách có chỉ mục, tức khi ta tạo ds thì Lisp vẫn giữ thứ tự thế nhưng bên trong đã đc đưa vào dạng dữ liệu chuẩn như ta thấy trên các phần mềm csdl, các cơ chế tìm kiếm sắp xếp đều đã chuẩn nên nó nhanh hơn ta duyệt nhiều. Mình đã thử bài toán như sau :


Cái đó thì đúng rồi. Nếu cần ổn định thì cách viết (reverse (assoc gt (mapcar 'reverse lst))) tất nhiên ổn định nhất, vì với list nào nó cũng làm vậy. Nếu so 5k item và phần tử đứng cuối thì nó nhanh rồi, nhưng với lượng item càng lớn, , giả sử như 1tr chẳng hạn, và item cần tìm lại nằm về phía gần đầu hơn, bác sẽ càng thấy sự khác biệt. Điều này phán đoán thôi là thấy liền hà :D. Nếu bác sử dụng list tầm 100k trở lại thì cách nào cũng vậy thôi, cũng không kịp chớp mắt.

P/s : code trên của bác dở quá, nên cái nào xét cũng lên đến giây. Ví dụ viết ntn thì dễ hiểu hơn : (nếu máy bác đủ khỏe thì cứ thử dịch gt đi, tăng list item lên huge xem sao ^^)

(setq gt 1) ;Tim thang co phan tu thu 2 bang 1, thang nay o vd cua bac la nam o cuoi list
;(setq lis = cai lis ban dau)
(defun c:test ()
;Reverse mapcar
(setq start (getvar "millisecs"))
(setq a (reverse (assoc gt (mapcar 'reverse lis))))
(setq tg1 (/ (- (getvar "millisecs") start) 1000.0))

;Vl-member-if
(setq start (getvar "millisecs"))
(setq b (car (vl-member-if '(lambda(x)(= (cadr x) gt)) lis)))
(setq tg2 (/ (- (getvar "millisecs") start) 1000.0))

;While
(setq start (getvar "millisecs"))
(while (and (car lis) (/= (cadr (setq c (car lis))) gt))(setq lis (cdr lis)))
(setq tg3 (/ (- (getvar "millisecs") start) 1000.0))
)

  • 0

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


#1196 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 24 June 2012 - 05:22 PM


Cái đó thì đúng rồi. Nếu cần ổn định thì cách viết (reverse (assoc gt (mapcar 'reverse lst))) tất nhiên ổn định nhất, vì với list nào nó cũng làm vậy. Nếu so 5k item và phần tử đứng cuối thì nó nhanh rồi, nhưng với lượng item càng lớn, , giả sử như 1tr chẳng hạn, và item cần tìm lại nằm về phía gần đầu hơn, bác sẽ càng thấy sự khác biệt. Điều này phán đoán thôi là thấy liền hà :D. Nếu bác sử dụng list tầm 100k trở lại thì cách nào cũng vậy thôi, cũng không kịp chớp mắt.

P/s : code trên của bác dở quá, nên cái nào xét cũng lên đến giây. Ví dụ viết ntn thì dễ hiểu hơn : (nếu máy bác đủ khỏe thì cứ thử dịch gt đi, tăng list item lên huge xem sao ^^)

Cám ơn Ketxu đã chỉ dẫn. Mình chỉnh một tý để test

(defun c:test ( / i j L lis1 lis gt a b c d e tg1 tg2 tg3 tg4 tg5)
(setq L (getint "\nNhap do dai :"))
(setq i 0 lis1 nil)
(while (< i L)
(setq lis1 (append lis1 (list (list i (- L i)))))
(setq i (1+ i))
)
(setq gt 1)
(setq lis lis1)
;Reverse mapcar
(setq start (getvar "millisecs"))
(setq a (reverse (assoc gt (mapcar 'reverse lis))))
(setq tg1 (/ (- (getvar "millisecs") start) 1000.0))
;Vl-member-if
(setq start (getvar "millisecs"))
(setq b (car (vl-member-if '(lambda(x)(= (cadr x) gt)) lis)))
(setq tg2 (/ (- (getvar "millisecs") start) 1000.0))
;While
(setq start (getvar "millisecs"))
(setq lis lis1)
(while (and (car lis) (/= (cadr (setq c (car lis))) gt))(setq lis (cdr lis)))
(setq tg3 (/ (- (getvar "millisecs") start) 1000.0))
(setq start (getvar "millisecs"))
(setq d (assoc gt (Mapcar 'reverse lis1)))
(setq tg4 (/ (- (getvar "millisecs") start) 1000.0))

(print a)
(print B)
(print c)
(print d)
(print tg1)
(print tg2)
(print tg3)
(print tg4)
Sau đây là kết quả :
Command: TEST
Nhap do dai :30000
(29999 1)
(29999 1)
(29999 1)
(1 29999)
0.016
0.031
0.062
0.016 0.016
Command:
P/S: Sau khi thay dổi cho gt lần lượt là 1, 29999 và 15000 thì cách viết thứ 2 dùng hàm vl-member-if xem ra nhanh nhất xét theo tổng quát.
Một lần nữa cám ơn Ketxu
  • 0

#1197 toanmda

toanmda

    biết zoom

  • Members
  • Pip
  • 19 Bài viết
Điểm đánh giá: 1 (bình thường)

Đã gửi 24 June 2012 - 05:52 PM

Nhờ các ace trên diễn đàn chỉ giúp,mình muốn viết một lisp vẽ ra một loạt các đường thẳng qua các điểm P1 P2 P3 ... Pn.
- Điểm P1 và số điểm n do mình chọn trước.(n có thể thay đổi)
- Điểm P2, P3 ... Pn xác định dựa vào điểm có trước đó, ở đây mình xác như sau

(Setq P2 (list (+ (car P1) 100) (+ (cadr P1) 100)))
(Setq P3 (list (+ (car P2) 100) (+ (cadr P2) 100)))
...

  • 0

#1198 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5454 Bài viết
Điểm đánh giá: 2626 (tuyệt vời)

Đã gửi 24 June 2012 - 06:22 PM


(defun C:VE()
(setq n (getint "\nSo doan thang can ve: "))
(setq p1 (getpoint "\nPick diem dau tien: "))
(repeat n
(setq p2 (list (+ (car p1) 100) (+ (cadr p1) 100)))
(entmake (list (cons 0 "LINE") (cons 10 p1) (cons 11 p2)))
(setq p1 p2)))

  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#1199 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5454 Bài viết
Điểm đánh giá: 2626 (tuyệt vời)

Đã gửi 25 June 2012 - 05:23 PM

Cám ơn Ketxu đã chỉ dẫn. Mình chỉnh một tý để test


(defun c:test ( / i j L lis1 lis gt a b c d e tg1 tg2 tg3 tg4 tg5)
(setq L (getint "\nNhap do dai :"))
(setq i 0 lis1 nil)
(while (< i L)
(setq lis1 (append lis1 (list (list i (- L i)))))
(setq i (1+ i))
)
(setq gt 1)
(setq lis lis1)
;Reverse mapcar
(setq start (getvar "millisecs"))
(setq a (reverse (assoc gt (mapcar 'reverse lis))))
(setq tg1 (/ (- (getvar "millisecs") start) 1000.0))
;Vl-member-if
(setq start (getvar "millisecs"))
(setq b (car (vl-member-if '(lambda(x)(= (cadr x) gt)) lis)))
(setq tg2 (/ (- (getvar "millisecs") start) 1000.0))
;While
(setq start (getvar "millisecs"))
(setq lis lis1)
(while (and (car lis) (/= (cadr (setq c (car lis))) gt))(setq lis (cdr lis)))
(setq tg3 (/ (- (getvar "millisecs") start) 1000.0))
(setq start (getvar "millisecs"))
(setq d (assoc gt (Mapcar 'reverse lis1)))
(setq tg4 (/ (- (getvar "millisecs") start) 1000.0))

(print a)
(print B)
(print c)
(print d)
(print tg1)
(print tg2)
(print tg3)
(print tg4)
Sau đây là kết quả :
Command: TEST
Nhap do dai :30000
(29999 1)
(29999 1)
(29999 1)
(1 29999)
0.016
0.031
0.062
0.016 0.016
Command:
P/S: Sau khi thay dổi cho gt lần lượt là 1, 29999 và 15000 thì cách viết thứ 2 dùng hàm vl-member-if xem ra nhanh nhất xét theo tổng quát.
Một lần nữa cám ơn Ketxu

Nếu mục đích là tìm thằng có phần tử thứ 2 bằng 1 (phần tử ở cuối lis) thì cần chi phải dùng những reverse, mapcar, vl-member-if... cho nó phức tạp và chậm nhỉ?
Chỉ cần dùng (assoc n list) là có kết quả tức thời luôn (0.000 giây).
Trong trường hợp của bài toán này thì: (assoc (- L gt) lis)
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#1200 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 25 June 2012 - 05:43 PM

Hi. bác Hạ vui tính quá, cái ni bác ấy lấy VD nên phần tử đầu và phần tử sau mới có quy luật như thế chứ ^^
  • 0

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