Chuyển đến nội dung
Diễn đàn CADViet
Jin Yong

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

Các bài được khuyến nghị

E đã thử delete theo ý bác Hà mà không thành công, chắc tại không hiểu ý. Mà em muốn chọn phương cần quay chỉ pick vào 2 điểm chứ không phải pick vào đường thẳng ạ, vì nhiêu khi phương cần quay không phải là đường thẳng mà chỉ là 2 điểm thôi ạ. Bác Hà chỉ rõ hơn cho em với, em không biết nhiều về lisp ạ! Thank bác. 

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

E đã thử delete theo ý bác Hà mà không thành công, chắc tại không hiểu ý. Mà em muốn chọn phương cần quay chỉ pick vào 2 điểm chứ không phải pick vào đường thẳng ạ, vì nhiêu khi phương cần quay không phải là đường thẳng mà chỉ là 2 điểm thôi ạ. Bác Hà chỉ rõ hơn cho em với, em không biết nhiều về lisp ạ! Thank bác. 

(defun c:roo(/ dt db tt )
 (princ "Chon Doi Tuong Can Quay: ") 
 (setq dt (ssget)
       db (getpoint "\nChon BasePoint:")
       tt (getpoint "\nChon Diem Dinh Huong: ") )
   (command ".rotate" dt "" "non" db "r" "non" db "non" tt pause)
) 

Của bạn đây. 

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
(defun c:ND()      (setvar "cmdecho" 0)
		   (setq a (getint "Nhap ti le dim: "))
		   (setvar "dimscale" a)	
		   (itoa a)
		   (setq ab (strcat "D" (itoa a)))
		   (command "DIMSTYLE" "s" ab)
)
(defun C:HD()
 (setvar "cmdecho" 0)
		   (setq a (getint "Nhap ti le dim muon lam hien hanh: "))	
		   (itoa a)
		   (setq ab (strcat "D" (itoa a)))
(wcmatch (cdr (assoc 0 lst)) "DIMENSION") (command "DIMSTYLE" "r" ab))))
;(princ))

E có 2 lisp, nd tạo dim mới từ D1, hd chọn dim hiện hành, đều là thao tác nhập từ bàn phím, em muốn gộp thành 1 lệnh thôi, tức là nếu dim chưa có sẵn thì tạo dim mới, nếu dim đã có sẵn thì chọn nó làm hiện hành. Các bác chỉnh sửa giúp em với ạ. Thank nhiều ạ!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Có thể hơi lạc đề với bài toán trên, cho em hỏi 1 chút.

Có thể hơi lạc đề với bài toán trên, cho em hỏi 1 chút.

Em có 1 đoạn như thế này thì viết kiểu dạng Function, Lambda, Mapcar....thì viết kiểu như thế nào các bác nhỉ?

Em có n = 5 và em muốn tạo ra 1 chuỗi: "1,2,3,4,5"

(progn
	        (setq k 2)
	    	(setq L1 "1")
	    	(repeat 5
			(setq L1 (strcat L1 "," (rtos k 2 0)))
                  	(setq k (+ k 1))
	        )
          	(princ L1)
          	(princ)
 )

 

Em có 1 đoạn như thế này thì viết kiểu dạng Function, Lambda, Mapcar....thì viết kiểu như thế nào các bác nhỉ?

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cái này không dùng mapcar mà dùng đệ quy.

 

(defun strcat1 (a n)
  (if (< a n)
    (strcat (itoa a) "," (strcat1 (1+ a) n))
    (itoa a)
  )
)
 
(strcat1 1 5)
  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

 

(defun c:ND()      (setvar "cmdecho" 0)
		   (setq a (getint "Nhap ti le dim: "))
		   (setvar "dimscale" a)	
		   (itoa a)
		   (setq ab (strcat "D" (itoa a)))
		   (command "DIMSTYLE" "s" ab)
)
(defun C:HD()
 (setvar "cmdecho" 0)
		   (setq a (getint "Nhap ti le dim muon lam hien hanh: "))	
		   (itoa a)
		   (setq ab (strcat "D" (itoa a)))
(wcmatch (cdr (assoc 0 lst)) "DIMENSION") (command "DIMSTYLE" "r" ab))))
;(princ))

E có 2 lisp, nd tạo dim mới từ D1, hd chọn dim hiện hành, đều là thao tác nhập từ bàn phím, em muốn gộp thành 1 lệnh thôi, tức là nếu dim chưa có sẵn thì tạo dim mới, nếu dim đã có sẵn thì chọn nó làm hiện hành. Các bác chỉnh sửa giúp em với ạ. Thank nhiều ạ!

Của bạn đây! Mà lisp dùng được hay không thì cũng phải phản hồi lại chứ, trình duyệt tự nhiên lỗi nên mình không tag vào code được đành để ngoài này

(defun c:ND(/ a b ab)

(setvar "cmdecho" 0)

(setq a (getint "Nhap ti le dim: "))

(setvar "dimscale" a)    

(itoa a)

(setq ab (strcat "D" (itoa a)))

(if (not (tblsearch "DIMSTYLE" ab))

(command "-DIMSTYLE" "s" ab)

(command "-DIMSTYLE" "r" ab) )

)

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

 

Cái này không dùng mapcar mà dùng đệ quy.

 

(defun strcat1 (a n)
  (if (< a n)
    (strcat (itoa a) "," (strcat1 (1+ a) n))
    (itoa a)
  )
)
 
(strcat1 1 5)

Dạ, em cảm ơn anh Tot77. Vậy em vẫn dùng cách của em ạ

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

- hihi Hieu có ghé ngang qua xem thử, nhoc mới học hàm grread, cũng thử múa rìu xíu tận dụng lsp roo của Hieu chỉnh lại = grread, vấn đề giới hạn góc nhập thì nhoc chưa xử đc, nhưng giữ được sợi thun quay quay cho Hieu ^^, quay tới đầu sẽ hiển thị góc phương vị tại chỗ đó ^^ dưới dòng command, khi nào ok, pick chuột trái tại vị trí mún xác định thì đoạn thẳng cũ sẽ chuyển tới đó, mấy anh có hứng giúp nhoc cải tiến phần nhập dữ liệu cho nhoc học hỏi thêm ^^, mò sáng giờ vẫn chưa pit với grread thì xử sao ^^

(defun c:roo(/ doigoc start end *error* vars ovars nvars dt db dh dg tt ent lst px pg p nhap edd info)
 (defun doigoc(goc)
  (rem (- 450.0 goc) 360.0))
 (defun start()
  (setq vars '("osmode" "cmdecho" "angdir" "angbase"))
  (setq ovars (mapcar 'getvar vars)
        nvars (mapcar 'setvar vars (list 0 0 1 (/ pi 2)))))
 (defun end()
  (and ovars (mapcar 'setvar vars ovars)))
 (defun *error* (ABC)
  (end))
 (vl-load-com) 
 (princ "Chon Doi Tuong Can Quay: ") 
 (setq dt (ssget)
       db (getpoint "\nChon BasePoint:")
       ent (ssname dt 0)
	   info (entget ent)
       lst (mapcar 'cdr (vl-remove-if-not '(lambda(x) (or (= (car x) 10) (= (car x) 11))) (entget ent))))
 (command "undo" "be")    
 (start)
 ;=========================================================================================
 (if (< (distance db (setq px (car lst))) (distance db (setq pg (cadr lst))))
 (alert (strcat "\nPhuong Vi cu <" (rtos (doigoc (* 180.0 (/ 1 pi) (angle px pg))) 2 2) ">"))
 (alert (strcat "\nPhuong Vi cu <" (rtos (doigoc (* 180.0 (/ 1 pi) (angle pg px))) 2 2) ">"))
 )
 ;=========================================================================================
 (if (< (distance db (setq px (car lst))) (distance db (setq pg (cadr lst))))
  (progn 
 ;==================================================================================================
(while (/= (car (setq nhap (grread t 15 0))) 3)
       (redraw)
	   (if (= (car nhap) 5)
	     (progn
	        (setq p (cadr nhap))
		   	(grdraw db p 1 1)
			(prompt (strcat "\nPhuong Vi hien la <" (rtos (doigoc (* 180.0 (/ 1 pi) (angle db p))) 2 2) ">"))
		 )
		)
)
p
(setq ang (angle db p))
(setq edd (entmod (append info (list (cons 10 db) (cons 11 (polar db ang (distance px pg)))))))
;====================================================================================================   
      (redraw)
   )
;======================================================================================================
  (progn 
 ;====================================================================================================
(while (/= (car (setq nhap (grread t 15 0))) 3)
       (redraw)
	   (if (= (car nhap) 5)
	     (progn
	        (setq p (cadr nhap))
		    (grdraw db p 1 1)
			(prompt (strcat "\nPhuong Vi hien la <" (rtos (doigoc (* 180.0 (/ 1 pi) (angle db p))) 2 2) ">"))
		 )
		)
)
p
(setq ang (angle db p))
(setq edd (entmod (append info (list (cons 10 db) (cons 11 (polar db ang (distance px pg)))))))
;===================================================================================================   
     (redraw)
   )
 ;-------------------------------------------------------
 ) ;end if 
 (end)
 (command "undo" "e")
 )
 
  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

- hi nhoc viết thí nghiệm  thử dùng grread ấy mà ^^, nếu lsp bạn Hieu viết để chuyển góc phương vị thì nhoc nghĩ chỉ để quay 1 đoạn thẳng là line, mục đích gì đó thì nhoc chưa pit, còn mún xoay nhóm obj hay polyline thì nhoc chưa làm nổi kaka.

- anh Ha giúp nhoc các dùng grread nhập liệu từ bàn phím mà có giới hạn như bạn Hieu hỏi từ 0-180, vậy là mình sẽ có 2 cách trả về 1 là pick 2 là nhập liệu, nhoc chưa pit phải làm sao ^^

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

- hi nhoc viết thí nghiệm  thử dùng grread ấy mà ^^, nếu lsp bạn Hieu viết để chuyển góc phương vị thì nhoc nghĩ chỉ để quay 1 đoạn thẳng là line, mục đích gì đó thì nhoc chưa pit, còn mún xoay nhóm obj hay polyline thì nhoc chưa làm nổi kaka.

- anh Ha giúp nhoc các dùng grread nhập liệu từ bàn phím mà có giới hạn như bạn Hieu hỏi từ 0-180, vậy là mình sẽ có 2 cách trả về 1 là pick 2 là nhập liệu, nhoc chưa pit phải làm sao ^^

Hàm grread chỉ nhập được 1 ký tự, hoặc pick 1 điểm, hoặc pick vào 1 icon... >> e rằng không thể dùng được để nhập 1 số có nhiều chữ số (VD: 123.45).

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Thanks nhóc và bác Hà đã nhiệt tình với vấn đề em nêu ra. Mục đích lisp roo của em là quay một tập hợp object theo góc phương vị. Hiện tại nội lực của em chưa đủ để xem code của nhóc viết thêm nên nhóc cứ đem lisp làm chuột bạch thoải mái. Nhóc có thể làm sao đó mà lisp sửa xong giống với cái nguyên thủy của tớ nhất kèm theo các điều kiện không enter chưa nhập số và nhập số trong khoảng [0 180] là thành công. :D

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

@nhoc: Grread thì không thể nhập số kiểu như bạn trình bày được

Nhưng kết hợp grread và dialog để nhập thì được

Ví dụ như TH này :

- Khi User rê chuột thì "Grread" phát huy tác dụng

- Khi User bấm phím số "56" độ chẳng hạn thì lúc đầu User phải bấm số 5 rồi mới bấm số 6

Ta đi thiết lập cho việc User bấm phím số đầu đưa vào hộp thoại. User chỉ việc nhập số tiếp theo trong hộp thoại. TH nhập số khác khoảng 0 -> 180 thì khi ok -> "Grread rê chuôt" phát huy tác dụng tiếp ^_^

Code mình viết để bạn tham khảo

 

(setq ok nil)
(while (and (or (/= (car (setq nhap (grread t 15 0))) 3) (< 47 (cadr nhap) 58)) (null ok))
       (redraw)
               (if (= (car nhap) 5)
                 (progn (princ "\n")
                    (princ (setq p (cadr nhap)))
                         )
                        )
      (if (= (car nhap) 2)
            (if (< 47 (cadr nhap) 58)
              (if (<= 0 (atoi (setq gocnhap (lisped (itoa (- (cadr nhap) 48)))) ) 180.0)
                 (progn (setq ok t) (alert (strcat "Gia tri goc nhap : " gocnhap)) (princ "\nGoc nhap : ") (princ gocnhap) )
      )))
)
(setq ok nil)
(while (and (or (/= (car (setq nhap (grread t 15 0))) 3) (< 47 (cadr nhap) 58)) (null ok))
       (redraw)
  (if (= (car nhap) 5)
    (progn
       (princ (setq p (cadr nhap)))
)
)
      (if (= (car nhap) 2)
(if (< 47 (cadr nhap) 58)
 (if (<= 0 (atoi (setq gocnhap (lisped (itoa (- (cadr nhap) 48)))) ) 180.0)
    (progn (setq ok t) (alert (strcat "Gia tri goc nhap : " gocnhap)) (princ gocnhap) )
      )))
)
  • Vote tăng 2

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Xin lỗi, trả lời nhầm.

 

Có hàm (substr st start count) trả về như Jin yêu cầu.

VD: (subst "abcd45e263" 3 5) = "cd45e"

Chào anh em làm trong nghành đóng tàu rất hay dùng lệnh "dimaligned" để đo các kích thước phục vụ hạ liệu tôn vỏ.

Anh có list nao giúp em đo khoảng cách giữa các giao điểm của các đường được nhanh không.

Rất mong được anh giúp. em cảm ơn!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Các bác ơi từ file text em có n dòng theo dạng "stt xa ya za", ví dụ như:

"1 100.000 200.000 3.456"

"2 2345.000 500.000 3.567"

....

"n 464.321 4000.7575 8.89"

Nhờ đọc được lisp của các bác @Doan Van Ha, @Gia bạch em cũng chuyển được các string text trên từng dòng về dạng list được rồi, dạng:

(1 100.000 200.000 3.456)

(2 2345.000 500.000 3.567)

........

Giờ em muốn vẽ một đường line hoặc polyline qua tọa độ của các điểm 1,2, ...n  này thì em phải dùng những hàm nào, các bác tư vấn và cho ví dụ để em vọc vạch với. Thanks các bác.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

- Vẽ pline qua các điểm đó chắc đc ^^ nhưng nhoc chưa pit cách add đc Z của từng điểm vào pline, nhoc cũng chưa hiểu cách chuyển từ text sang lst của Hieu như thế nào, quét tới đâu chuyển tới đó hay quét hết 1 lúc rùi chuyển lun, nhoc có code mấy  dòng Hieu thử xem sao

(defun c:rrr(/ )
(setq a '(1 2 3 4))
(setq b '(2 7 8 9))
(setq lst_new (mapcar '(lambda (x) (cdr x)) (list a b)))
(K:pline lst_new nil nil nil)
) 
;;;;;;;;;;;============================================================
(defun K:pline (listpoint closed Layer clr / Lst)
	(setq Lst (list '(0 . "LWPOLYLINE")'(100 . "AcDbEntity")
	(cons 8 (if Layer Layer (getvar "Clayer")))
	(cons 62 (if clr clr 256))
    '(100 . "AcDbPolyline")
	(cons 90 (length listpoint))
	(cons 70 (if closed 1 0))))
	(foreach PP listpoint	(setq Lst (append Lst (list (cons 10 PP)))))
(entmakex Lst))
	;end;================================= 

- biến a, b giả sử tương ứng với các lst tọa độ trả về của Hieu

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

- Vẽ pline qua các điểm đó chắc đc ^^ nhưng nhoc chưa pit cách add đc Z của từng điểm vào pline, nhoc cũng chưa hiểu cách chuyển từ text sang lst của Hieu như thế nào, quét tới đâu chuyển tới đó hay quét hết 1 lúc rùi chuyển lun, nhoc có code mấy  dòng Hieu thử xem sao

(defun c:rrr(/ )
(setq a '(1 2 3 4))
(setq b '(2 7 8 9))
(setq lst_new (mapcar '(lambda (x) (cdr x)) (list a b)))
(K:pline lst_new nil nil nil)
) 
;;;;;;;;;;;============================================================
(defun K:pline (listpoint closed Layer clr / Lst)
	(setq Lst (list '(0 . "LWPOLYLINE")'(100 . "AcDbEntity")
	(cons 8 (if Layer Layer (getvar "Clayer")))
	(cons 62 (if clr clr 256))
    '(100 . "AcDbPolyline")
	(cons 90 (length listpoint))
	(cons 70 (if closed 1 0))))
	(foreach PP listpoint	(setq Lst (append Lst (list (cons 10 PP)))))
(entmakex Lst))
	;end;================================= 

- biến a, b giả sử tương ứng với các lst tọa độ trả về của Hieu

thanks nhóc, một loạt hàm chưa học, chạy trước ô tô mệt ghê. Cho tớ hỏi mình có thể dùng đơn giản hơn như là dùng (command  ".polyline" ......) được không nhóc???

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

- ah đc ^^, nhoc ít xài bên 3d nên ít để ý trục Z, mới xực nhớ có đọc qua dùng lệnh 3dpoly có thể add Z lun ^^, code sẽ đc viết lại như thế này ^^

(defun c:rrr(/ )
(setq a '(1 2 3 4))
(setq b '(2 7 8 9))
(setq lst_new (mapcar '(lambda (x) (cdr x)) (list a b)))
(apply 'command (append (list ".3dPoly") lst_new (list "")))
) 

- các điểm đó sẽ đúng theo lst vd:  x=2 y=3 z=4, 

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

@nhoc: Grread thì không thể nhập số kiểu như bạn trình bày được

Nhưng kết hợp grread và dialog để nhập thì được

Ví dụ như TH này :

- Khi User rê chuột thì "Grread" phát huy tác dụng

- Khi User bấm phím số "56" độ chẳng hạn thì lúc đầu User phải bấm số 5 rồi mới bấm số 6

Ta đi thiết lập cho việc User bấm phím số đầu đưa vào hộp thoại. User chỉ việc nhập số tiếp theo trong hộp thoại. TH nhập số khác khoảng 0 -> 180 thì khi ok -> "Grread rê chuôt" phát huy tác dụng tiếp ^_^

 

Hàm grread chỉ nhập được 1 ký tự, hoặc pick 1 điểm, hoặc pick vào 1 icon... >> e rằng không thể dùng được để nhập 1 số có nhiều chữ số (VD: 123.45).

 

Chỉ được nhập 1 ký tự không có nghĩa là ta không thể có cách nào nhập 2 ký tự hoặc hơn khi vận dụng nó. Cho grread vào vòng lặp while và khai báo điều kiện thoát lặp thì ta có thể nhập bao nhiêu ký tự cũng được.

 

Ví dụ như cách làm của Tue_NV, bạn hoàn toàn có thể thay thế việc gọi hộp thoại bằng 1 hoặc nhiều lần grread nữa. theo hướng giải quyết như của bạn, ta có thể dùng while hoặc lặp đệ quy để thay cho dialog đều được. Với cách này, thậm chí có thể viết để đối tượng xoay theo thời gian thực khi người dùng nhập số hoặc di chuyển con trỏ luôn nữa cơ.

 

Trước đây mình có chia sẻ lên diễn đàn lisp máy tính dòng lệnh. Phương thức nhập liệu mình sử dụng cũng tương tự vậy.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Các bạn cho mình hỏi.

Mình đang viết một lisp, và trong lisp này mình muốn gọi để thực thi một lisp khác được không, nếu được thì câu lệnh như thế nào.

Mình cảm ơn!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay

×