Đế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
2848 replies to this topic

#1381 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 14 October 2012 - 09:58 AM

"[yêu cầu]Viết Lisp xắp xếp các List..."
Tôi có hai list như sau:
- list 1 chứa các giá trị: (setq ddat '(4 2 7 1 8 3 5 6 9))
- list 2 chứa các text: (setq tso '(d b g a h c e f i))
Nhờ các Bạn giúp CODE để xắp xếp hai list trên sao cho ra kết quả như sau:
...(xapxep ddat tso)...
thì trả về hai list: ( 1 2 3 4 5 6 7 8 9) và (a b c d e f g h i) tương ứng.

Của bạn đây :

(defun sapxep(l1 l2 / lst)
(list
(mapcar 'car (setq lst (vl-sort (mapcar '(lambda(x y) (cons x y)) ddat tso) '(Lambda (x y) (< (car x) (car y))))))
(mapcar 'cdr lst)
)
)

(vl-sort ddat '(lambda (e1 e2) (< e1 e2)))
(vl-sort tso '(lambda (e1 e2) (< e1 e2)))

Hình như không đúng câu hỏi của bạn lenhatanh
Và câu này thì sai rồi bác
(vl-sort tso '(lambda (e1 e2) (< e1 e2)))
  • 0

#1382 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 14 October 2012 - 02:14 PM

Câu hỏi của lenhatanh tối nghĩa vậy :) Người hỏi chưa phân biệt được SYMBOL và STRING, làm câu trả lời cũng loằng ngoằng thêm :)
  • 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


#1383 lenhatanh

lenhatanh

    biết vẽ polygon

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

Đã gửi 14 October 2012 - 05:25 PM

Của bạn đây :

 (defun sapxep(l1 l2 / lst) (list (mapcar 'car (setq lst (vl-sort (mapcar '(lambda(x y) (cons x y)) ddat tso) '(Lambda (x y) (< (car x) (car y)))))) (mapcar 'cdr lst) ) ) 
Hình như không đúng câu hỏi của bạn lenhatanh Và câu này thì sai rồi bác (vl-sort tso '(lambda (e1 e2) (< e1 e2)))

Cám ơn các Bạn !
  • 0

#1384 avi612

avi612

    biết lệnh move

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

Đã gửi 15 October 2012 - 10:52 AM

Mình có một bài toán như sau nhờ mọi người góp ý cách giải quyết:
----
Mình có 1 tập hợp các đối tượng được sắp xếp theo trường hợp ô lưới và mình muốn sử lý tùy biến nó theo 3 cách.
- Sử lý tập đối tượng đó theo phương X.
- Sử lý tập đối tượng đó theo phương Y
- Sử lý tập đối tượng đó theo thứ tự được chọn.
Ví dụ:
Mình có 1 tập hợp chuỗi. và mình muốn thay thế chuỗi này vào 1 chuổi khác cùng số lượng.

Minh họa: lấy theo phương X
1 2 3 4 5 6 7 8
A B C D E F G H
9 10 11 12 13 14 15 16

==> Kết quả: 1 2 3 4 5 6 7 8 A B C D E F G H 9 10 11 12 13 14 15 16

Minh họa: lấy theo phương Y
1 2 3 4 5 6 7 8
A B C D E F G H
9 10 11 12 13 14 15 16

==> Kết quả: 1 A 9 2 B 10 3 C 11 4 D 12 5 E 13 6 F 14 7 G 15 8 H 16
Và sử lý theo thứ tự được chọn cũng tương tự đối với 2 cách trên. Vậy mình phải sử lý như thế nào.
  • 0

#1385 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 15 October 2012 - 11:42 AM

Đọc hoài câu hỏi của bạn, kể cả ví dụ, vẫn chưa hiểu được ý bạn.
Khái niệm "thay thế" trong ví dụ: không hiểu. Trong ví dụ có thấy cái gì thay thế cho cái gì đâu?
Khái niệm: sắp xếp theo lưới ô": cũng không hiểu luôn.
Bạn có cách chi giải thích trần truồng hơn một chút được không?
  • 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.


#1386 gia_bach

gia_bach

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 1431 Bài viết
Điểm đánh giá: 1425 (rất tốt)

Đã gửi 15 October 2012 - 12:30 PM

Mình có một bài toán như sau nhờ mọi người góp ý cách giải quyết:
----
Mình có 1 tập hợp các đối tượng được sắp xếp theo trường hợp ô lưới và mình muốn sử lý tùy biến nó theo 3 cách.
- Sử lý tập đối tượng đó theo phương X.
- Sử lý tập đối tượng đó theo phương Y
- Sử lý tập đối tượng đó theo thứ tự được chọn.
Ví dụ:
Mình có 1 tập hợp chuỗi. và mình muốn thay thế chuỗi này vào 1 chuổi khác cùng số lượng.

==> Kết quả: 1 2 3 4 5 6 7 8 A B C D E F G H 9 10 11 12 13 14 15 16

==> Kết quả: 1 A 9 2 B 10 3 C 11 4 D 12 5 E 13 6 F 14 7 G 15 8 H 16
Và sử lý theo thứ tự được chọn cũng tương tự đối với 2 cách trên. Vậy mình phải sử lý như thế nào.

Sort theo phương X.Y thì tham khảo Lisp của Lee-Mac :

;; Renumber Text - Lee Mac - 2011 - www.lee-mac.com
;; Prompts for a selection of Text / MText objects and renumbers the
;; contents in the chosen direction, based on the text alignment point.
(defun c:rt ( / ent inc lst sel srt )
(defun LM:GroupByFunction ( lst fun / tmp1 tmp2 x1 )
(if (setq x1 (car lst))
(progn
(foreach x2 (cdr lst)
(if (fun x1 x2)
(setq tmp1 (cons x2 tmp1))
(setq tmp2 (cons x2 tmp2))) )
(cons (cons x1 tmp1) (LM:GroupByFunction tmp2 fun)) ) ) )
(defun LM:TextInsertion ( elist )
(if
(or
(eq "MTEXT" (cdr (assoc 0 elist)))
(and
(zerop (cdr (assoc 72 elist)))
(zerop (cdr (assoc 73 elist))) ) )
(cdr (assoc 10 elist))
(cdr (assoc 11 elist)) ) )
(if (setq sel (ssget "_:L" '((0 . "MTEXT,TEXT"))))
(progn
(initget "LTR RTL TTB BTT")
(setq *dir*
(cond
( (getkword
(strcat "\nDirection? [LTR/RTL/TTB/BTT] <"
(setq *dir* (cond ( *dir* ) ("LTR"))) ">: " ) ) )
( *dir* ) ) )
(repeat (setq inc (sslength sel))
(setq ent (entget (ssname sel (setq inc (1- inc))))
lst (cons (list (LM:TextInsertion ent) ent) lst) ) )
(setq inc 0)
(foreach row
(apply 'vl-sort
(cond
( (member *dir* '("LTR" "RTL"))
(if (eq "LTR" *dir*)
(setq srt (function (lambda ( a b ) (< (caar a) (caar B)))))
(setq srt (function (lambda ( a b ) (> (caar a) (caar B))))) )
(list
(LM:GroupByFunction lst (lambda ( a b ) (equal (cadar a) (cadar B) 0.1)))
(function (lambda ( a b ) (> (cadaar a) (cadaar B)))) ) )
( (member *dir* '("TTB" "BTT"))
(if (eq "TTB" *dir*)
(setq srt (function (lambda ( a b ) (> (cadar a) (cadar B)))))
(setq srt (function (lambda ( a b ) (< (cadar a) (cadar B))))) )
(list
(LM:GroupByFunction lst (lambda ( a b ) (equal (caar a) (caar B) 0.1)))
(function (lambda ( a b ) (< (caaar a) (caaar B)))) ) ) ) )
(foreach item (vl-sort row srt)
(entmod
(subst
(cons 1 (itoa (setq inc (1+ inc))))
(assoc 1 (cadr item))
(cadr item) ) ) ) ) ) )
(princ))
(vl-load-com)

  • 1

#1387 avi612

avi612

    biết lệnh move

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

Đã gửi 15 October 2012 - 12:44 PM

Mình làm cái hình minh họa cho rõ hơn rồi:

http://qlda.spaceaa..../download/70393
  • 0

#1388 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 15 October 2012 - 02:02 PM

Phương án: trong mỗi tập chọn (tập gốc, gọi là lst1 và tập cần thay thế, gọi là lst2), bạn sắp xếp tăng dần theo nguyên tắc:
- Nếu tọa độ X bằng nhau thì tăng dần theo Y.
- Nếu tọa độ Y bằng nhau thì tăng dần theo X.
- Khi đó bạn sẽ có 2 tập tương ứng (lst1 và lst2), quan hệ một đối một.
- Lặp n lần, mỗi lần entmod mỗi phần tử trong lis2 bởi 1 phần tử trong lst1 => sẽ có list thay thế.
Phương án này có thể áp dụng cho cả 3 kiểu thay thế của bạn. Tham khảo 1 hàm sắp xếp mà tôi đã dùng với nguyên lý gần giống bạn:
;---- Sap xep theo X tang dan, neu X bang nhau thi sap xep theo Y tang dan, by HA.
(setq lst (vl-sort lst '(lambda (e1 e2) (if (/= (car e1) (car e2)) (< (car e1) (car e2)) (< (cadr e1) (cadr e2))))))
Trong hàm trên, để chính xác, nên dùng EQUAL.
Hy vọng bạn làm được.
P/S: lisp tham khảo của bác Gia_bach không đúng ý đồ của bạn.
P/S: xem lại thì ví dụ không giống với hình minh họa của bạ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.


#1389 avi612

avi612

    biết lệnh move

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

Đã gửi 15 October 2012 - 03:02 PM

Đúng là ví dụ trên ko giống với hình minh họa vì mình sẽ vận dụng cú pháp của nó cho những trường hợp khác nhau chứ không hẳn là chỉ định cho 1 trường hợp cụ thể nào...
Cảm ơn đã góp ý, mình sẽ áp dụng thử. Thanks
  • 0

#1390 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 22 October 2012 - 05:02 PM

Delete dòng này đi:
(entdel name)
  • 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.


#1391 avi612

avi612

    biết lệnh move

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

Đã gửi 26 October 2012 - 03:58 PM

1. Cho mình hỏi về cách sử dụng và chức năng của hàm "defun S::...." mình seach trên forum thì có 1 vài bài viết có sử dụng hàm này nhưng không thấy hướng dẫn cách vận dụng nó....
2. Một điều nữa là nếu như mình đặt tên 1 biến "ABC" nào đó dùng cho 2 file Lisp khác nhau và mang giá trị khác nhau thì trong quá trình làm việc có xảy ra xung đột giữa 2 giá trị được gán của biến này ko.
VD:
(setq ABC "giá trị ở Lisp 1") --> Dòng này ở lisp 1
(setq ABC "giá trị ở Lisp 2") --> Dòng này ở lisp 2
Khi lisp 1 và lisp 2 được add vào và sử dụng thì có xảy ra lỗi ko.
  • 0

#1392 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 26 October 2012 - 04:55 PM

Trả lời câu 2 cho bạn: lỗi hay không lỗi là tùy thuộc lệnh này có hứng kết quả của lệnh kia không. Xem chuỗi ví dụ này chắc bạn hiểu.
Test theo thứ tự trên xuống.

(defun C:HA1a() ;ham thu 1 sinh ra bien a, khong khu bien a.
(setq a 0)
(princ (strcat "\n " (itoa a)))
(princ))
(defun C:HA2() ;ham thu 2 hung gia tri cua ham khac => co the bi loi
(or a (setq a 1))
(princ (strcat "\n " (itoa (/ 5 a))))
(princ))
(defun C:HA3() ;ham thu 3 set gia tri moi cho a => luon luon khong loi
(setq a 1)
(princ (strcat "\n " (itoa (/ 5 a))))
(princ))
(defun C:HA1b( / a) ;ham thu 1 sinh ra bien a, khu bien a.
(setq a 0)
(princ (strcat "\n " (itoa a)))
(princ))
(defun C:HA4() ;ham thu 4 hung gia tri cua ham khac, nhung da bi khu roi => khong loi
(or a (setq a 1))
(princ (strcat "\n " (itoa (/ 5 a))))
(princ))

  • 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.


#1393 ThuyLinh313

ThuyLinh313

    biết lệnh mtext

  • Members
  • PipPipPipPip
  • 288 Bài viết
Điểm đánh giá: 142 (tàm tạm)

Đã gửi 17 November 2012 - 03:03 PM

Các bạn cho mình hỏi: Có cách nào để xác định 1 block att có sử dụng field không? hoặc rộng hơn là bất kỳ đối tượng nào có sử dụng field.
Mình định ứng dụng nó để tự động lấy tập hợp các đối tượng cho lệnh UPDATEFIELD, tránh việc phải Regen bản vẽ.
  • 0

#1394 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 17 November 2012 - 03:39 PM

Đây ban! Cái này chọn trực tiếp vào field trong block_att. Từ đó suy cho các đối tượng khác.

(setq field (cdr (assoc 3 (entget (cdr (assoc 360 (entget (CAR (NENTSEL "Chon Block_Att co chua field: ")))))))))

  • 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.


#1395 ThuyLinh313

ThuyLinh313

    biết lệnh mtext

  • Members
  • PipPipPipPip
  • 288 Bài viết
Điểm đánh giá: 142 (tàm tạm)

Đã gửi 17 November 2012 - 04:04 PM

cảm ơn bạn!
hix, nó nằm sâu quá! kiểu này ý định của mình phá sản roài :(
  • 0

#1396 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 17 November 2012 - 04:17 PM

Một ý tưởng hay sao lại dễ bị phá sản bởi chuyện sâu/cạn?
Bạn cứ duyệt entnext xem sao, chắc được chứ hè?
  • 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.


#1397 ThuyLinh313

ThuyLinh313

    biết lệnh mtext

  • Members
  • PipPipPipPip
  • 288 Bài viết
Điểm đánh giá: 142 (tàm tạm)

Đã gửi 19 November 2012 - 08:35 AM

Nếu bản vẽ chứa ít đối tượng thì việc regen bản vẽ không vấn đề gì. Mình không muốn regen trong trường hợp bản vẽ chứa số lượng lớn đối tượng. trong trường hợp đó, nếu ta cứ entnext thì mình chắc là không nhanh hơn việc regen là bao.
Do ý định ban đầu phá sản nên mình tính đến 1 giải pháp khác khả dĩ hơn. Chỉ UpdateField cho các đối tượng trong phạm vi nhìn thấy trên màn hình (giống hatch). cảm ơn bạn đã nhiệt tình :)

;;; reset field - Thuylinh313
(defun c:rf (/ x y c)
(setq x (getvar"screensize")
y (* 0.5 (getvar"viewsize"))
c (getvar "viewctr"))
(vl-cmdf "UPDATEFIELD"
(ssget "c"
(polar (polar c (* 0.5 pi) y) pi (/(* y (car x)) (cadr x)))
(polar (polar c (* -0.5 pi) y) 0 (/(* y (car x)) (cadr x)))
'((0 . "INSERT,*TEXT"))) "")
(princ))

  • 1

#1398 ThuyLinh313

ThuyLinh313

    biết lệnh mtext

  • Members
  • PipPipPipPip
  • 288 Bài viết
Điểm đánh giá: 142 (tàm tạm)

Đã gửi 30 November 2012 - 09:11 AM

E nghĩ có thể xài qua Reactor.
1 ví dụ :

(defun ST:Reactor-Clear (lstReactor)
(foreach item lstReactor (if (eval item) (progn (vlr-remove (eval item))(set item nil))))
)

(defun ST-Get-List-Command(objReactor lstOfCommand)
(setq #lstCmds (reverse (cons (car lstOfCommand) (reverse #lstCmds)))))

(ST:Reactor-Clear '(#CmdList1 #CmdList2))
(setq #CmdList1 (vlr-editor-reactor nil '((:vlr-commandended . ST-Get-List-Command))))
(setq #CmdList2 (vlr-editor-reactor nil '((:vlr-unknownCommand . ST-Get-List-Command))))
#lstCmds lưu lại list các lệnh known và unknown.Khi sử dụng lệnh AA thì lấy last list này

Ketxu có thể hướng dẫn cụ thể cách dùng mấy hàm trên để lấy lệnh cuối không? Mình cũng đang cần lấy lệnh cuối nhưng không hiểu mấy hàm trên sử dụng thế nào.
  • 0

#1399 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 30 November 2012 - 11:55 AM

Bạn chỉ cần đặt các hàm đó cho load lên thôi.
Phần :

(defun ST:Reactor-Clear (lstReactor)
(foreach item lstReactor (if (eval item) (progn (vlr-remove (eval item))(set item nil))))
)

(ST:Reactor-Clear '(#CmdList1 #CmdList2))


nhằm mục đích clear reactor trước đó.

Biến #lstCmds đã lưu lại các lệnh đã thực hiện (kể từ khi load lisp) rồi, bạn kiểm tra giá trị biến này nhé.
Có thể đổi vlr-commandended thành :vlr-commandWillStart để bắt cả trường hợp người dùng đánh lệnh rồi esc luôn.
  • 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


#1400 ThuyLinh313

ThuyLinh313

    biết lệnh mtext

  • Members
  • PipPipPipPip
  • 288 Bài viết
Điểm đánh giá: 142 (tàm tạm)

Đã gửi 06 December 2012 - 01:46 PM

Đoạn code trên không ổn ketxu ạ. nó chỉ có tác dụng với các lệnh của cad. có 2 vấn đề sảy ra nó không giải quyết được:
- Các lệnh lisp (defun c:lenh....) nó hoàn toàn không nhận biết.
- Các lệnh lisp có sử dụng hàm command bên trong, nó sẽ lấy luôn command cuối cùng sử dụng trong lệnh lisp đó. mà thường thì đó là các lệnh UCS hoặc Undo.
Lệnh mà mình muốn lấy là lệnh cuối cùng giống như khi ta vừa sử dụng 1 lệnh, space hay enter tiếp thì cad gọi lại lệnh vừa sử dụng í.
  • 0