Đến nội dung


Hình ảnh
- - - - -

[ Nhờ hoàn thiện] lisp vẽ line !


  • Please log in to reply
36 replies to this topic

#1 hanam1210

hanam1210

    biết vẽ pline

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

Đã gửi 16 October 2011 - 03:18 AM

Cái lisp này em viết nhằm mục đích vẽ ra 1 line trong các trường hợp riêng phục vụ cho vẽ và tính taluy san nền.
Cụ thể theo yêu cầu:
+ Lisp lấy giá trị từ text có sẵn ( giá trị là A) và vẽ ra line theo cách pcik điểm P1 và P2 , nó sẽ vẽ ra đoạn P1P2 thuộc layer GRID_TL có màu 3 và chiều dài đoạn P1P2 =kc được tính trong các trường hợp sau:
TH1: nếu A< -7, kc= A*Kđào +( phần nguyên của A/7 )*2
TH2: nếu -7 < A < 0, kc= A*Kđào
TH3: nếu 0<A< 7, kc= A*1.5
TH4: nếuA >7, kc= A*1.5 +( phần nguyên của A/5 )*2
D­ưới đây là phần code mà e đã loay hoay viết. Đợt trước nó chạy được. Nhưng đợt này bị lỗi mất trường hợp -7< A <7 không hiểu vì sao. Các anh trên diễn đàn hoàn thiện hoặc viết mới giúp em để nó không bị lỗi nữa ạ. EM xin cảm ơn !
Hệ số Kđào trong lisp của em viết để mặc định bằng 1, Các anh bổ sung nó giúp em với ạ, K đào do người dùng chỉ cần nhập vào một lần trong cả bản vẽ đó trong mỗi lần mở lên
.Giống đoạn code này sao ý:
(if (= Ty_le nil) (progn
(setq Ty_le (getreal "\n Kđào"))
(setq He_so (/ 1 Ty_le))
(setq He_so2 (* He_so He_so))
)
)


(defun c:lo (/ kc kc1 ot k1)
(command "layer" "N" "GRID_TL" "S" "GRID_TL" "color" 3 "" "")
(repeat 10000
(setq p1 (getpoint "\n Pick diem: "))
(setq p2 (getpoint "\n Pick diem: "))
(setq kc (entget (car (entsel "\n Chenh cao: "))))
(setq otext (assoc 1 kc))
(setq ot (cdr otext))
(setq ot (read (substr ot 1)))
(setq g (angle p1 p2))
(if (< ot -7)
(progn
(setq KC1 (* (abs ot) 1))
(setq k1 (* 2 (fix (/ (abs ot) 5))))
(setq KC1 (+ k1 KC1))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)
(if (and (< ot 0) (> ot -7))
(progn
(setq KC1 (* (abs ot) 1))
(setq k1 (* 2 (fix (/ (abs ot) 5))))
(setq KC1 (+ k1 KC1))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)
(if (and (> ot 0) (< ot 7))
(progn
(setq kc1 (* ot 1.5))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)
(if (> ot 7)
(progn
(setq KC1 (* (abs ot) 1))
(setq k1 (* 2 (fix (/ (abs ot) 5))))
(setq KC1 (+ k1 KC1))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)

(princ)
)

)

  • 0

#2 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 16 October 2011 - 09:26 AM

Cái lisp này em viết nhằm mục đích vẽ ra 1 line trong các trường hợp riêng phục vụ cho vẽ và tính taluy san nền.
Cụ thể theo yêu cầu:
+ Lisp lấy giá trị từ text có sẵn ( giá trị là A) và vẽ ra line theo cách pcik điểm P1 và P2 , nó sẽ vẽ ra đoạn P1P2 thuộc layer GRID_TL có màu 3 và chiều dài đoạn P1P2 =kc được tính trong các trường hợp sau:
TH1: nếu A< -7, kc= A*Kđào +( phần nguyên của A/7 )*2
TH2: nếu -7 < A < 0, kc= A*Kđào
TH3: nếu 0<A< 7, kc= A*1.5
TH4: nếuA >7, kc= A*1.5 +( phần nguyên của A/5 )*2
D­ưới đây là phần code mà e đã loay hoay viết. Đợt trước nó chạy được. Nhưng đợt này bị lỗi mất trường hợp -7< A <7 không hiểu vì sao. Các anh trên diễn đàn hoàn thiện hoặc viết mới giúp em để nó không bị lỗi nữa ạ. EM xin cảm ơn !
Hệ số Kđào trong lisp của em viết để mặc định bằng 1, Các anh bổ sung nó giúp em với ạ, K đào do người dùng chỉ cần nhập vào một lần trong cả bản vẽ đó trong mỗi lần mở lên
.Giống đoạn code này sao ý:
(if (= Ty_le nil) (progn
(setq Ty_le (getreal "\n Kđào"))
(setq He_so (/ 1 Ty_le))
(setq He_so2 (* He_so He_so))
)
)


(defun c:lo (/ kc kc1 ot k1)
(command "layer" "N" "GRID_TL" "S" "GRID_TL" "color" 3 "" "")
(repeat 10000
(setq p1 (getpoint "\n Pick diem: "))
(setq p2 (getpoint "\n Pick diem: "))
(setq kc (entget (car (entsel "\n Chenh cao: "))))
(setq otext (assoc 1 kc))
(setq ot (cdr otext))
(setq ot (read (substr ot 1)))
(setq g (angle p1 p2))
(if (< ot -7)
(progn
(setq KC1 (* (abs ot) 1))
(setq k1 (* 2 (fix (/ (abs ot) 5))))
(setq KC1 (+ k1 KC1))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)
(if (and (< ot 0) (> ot -7))
(progn
(setq KC1 (* (abs ot) 1))
(setq k1 (* 2 (fix (/ (abs ot) 5))))
(setq KC1 (+ k1 KC1))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)
(if (and (> ot 0) (< ot 7))
(progn
(setq kc1 (* ot 1.5))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)
(if (> ot 7)
(progn
(setq KC1 (* (abs ot) 1))
(setq k1 (* 2 (fix (/ (abs ot) 5))))
(setq KC1 (+ k1 KC1))
(setq p3 (polar P1 G KC1))
(command "line" p1 p3 "")
)
)

(princ)
)

)

Nói chung, Lisp của bạn còn nhiều điều phải bàn tới:
1). Nếu có tới 4 trường hợp như thế thì nên dùng hàm cond chứ không nên dùng hàm if.
2). Các trường hợp bạn xét là chưa đủ, như khi dấu "=" xãy ra thì sao.
3). Không nên dùng hàm repeat mà nên dùng while.
4). Thiếu đặt osnap nên bạn bị lỗi...
Nhưng mới viết và mày mò đến tận 3h sáng thì bạn sẽ tiến triển không lâu nữa.
Tôi tạm sửa cho bạn như dưới đây. Nếu có gì chưa ưng ý thì post lên nhé.
Thân thương!

(defun c:lo (/ kc1 ot p1 p2)
(setq oldcm (getvar "cmdecho") oldos (getvar "osmode") )
(command "undo" "begin")
(if (not (tblsearch "layer" "GRID_TL")) (command "layer" "N" "GRID_TL" "S" "GRID_TL" "color" 3 "" ""))
(or *hsd* (setq *hsd* 1.0))
(setq hsd (getreal (strcat "\nHe so dao <" (rtos *hsd* 2) ">: ")))
(if (not hsd) (setq hsd *hsd*) (setq *hsd* hsd))
(while (setq p1 (getpoint "\n Pick diem 1: "))
(setq p2 (getpoint "\n Pick diem 2: "))
(setq ot (read (substr (cdr (assoc 1 (entget (car (entsel "\n Chenh cao: "))))) 1)))
(setvar "cmdecho" 0) (setvar "osmode" 0)
(cond
((< 0 ot 7) (setq kc1 (* (abs ot) 1.5)))
(T (setq kc1 (+ (* 2 (fix (/ (abs ot) 5))) (* (abs ot) hsd)))))
(command "line" p1 (polar p1 (angle p1 p2) kc1) "")
(setvar "cmdecho" oldcm) (setvar "osmode" oldos))
(command "undo" "end")
(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.


#3 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 16 October 2011 - 09:34 AM

Bạn đã tự viết đến đó rồi thì cố gắng tự hoàn thiện đi thôi. Cố gắng vận động mình đi một chút
Một số góp ý để bạn sửa :
1 - Nếu dùng command tạo Layer và Line, hãy dũng Make thay vì New để set layer vừa tạo làm Layer hiện thời
2 - Lấy giá trị số của text A, đơn giản nhất hãy dùng (distof string) , trong đó string là dãy string thu được của text chênh cao
3 - Với số lần lặp chưa biết trước, hãy sử dụng While (chứ không ai lại viết repeat 10000 cả :) )
Cấu trúc tham khảo :

(while (setq p2 (getpoint (setq p1 (getpoint "\nP1 :")) "\nP2 :"))


; làm gì đó
)

Những thứ trong vòng lặp trên sẽ làm việc khi bạn còn cung cấp đủ 2 điểm P1, P2
4 - Với điều kiện rẽ nhiều nhánh, hãy sử dụng hàm COND .Nhất là trong trường hợp này, các thao tác ở các trường hợp giống hệt nhau, chỉ khác mỗi cách tính kc. Bạn bật Help Develop lên, đồng thời xem cách dùng COND trong ví dụ là lisp SN gần đây nhất ketxu viết giúp bạn hôm qua, nếu không hiểu thì có thể post tiếp lên đây :)
5 - Các trường hợp rẽ nhánh của bạn không bao hết trường điều kiện, việc gì sẽ xảy ra khi A = -7 , 0 , 7 ?
6 - Đoạn code gán giá trị mặc định cho biến có thể viết gọn lại là :

(or hs (setq hs (getreal "\nNhap he so :")) (setq hs 1.0))

Khi xét đến dòng code này, hàm or sẽ đánh giá từng biểu thức. Bạn có thể hiểu nôm na đoạn này là :
Hoặc hs - Hoặc (setq hs (getreal "\nNhap he so :")) - Hoặc (setq hs 1.0) , cái nào mang giá trị Nil thì nó bỏ qua, cái nào trả về (not Nil) thì nó theo cái đó (theo thứ tự trái sang phải). Như là bạn chọn mua 1 trong 3 mặt hàng vậy. Không mua mặt hàng 1 => chuyển sang 2, ưng mua 2 thì xong phiên chợ, không ưng thì xem sang 3.
=> Tương đương với lần đầu chạy lisp, hs chưa được đặt giá trị (Nil) => Hàm Or xét tiếp dòng thứ 2 là (setq hs (getreal "\nNhap he so :"))
+ Tại đây nếu ta nhập giá trị cho hs => Not nil => Hàm Or trả về T và hs có giá trị bằng giá trị nhập vào, thoát khỏi hàm.
+ Tại đây nếu ta không nhập giá trị cho nó (ấn Space) => (setq hs (getreal "\nNhap he so :")) trả về Nil => Hàm or nhảy sang biểu thức cuối cùng là (setq hs 1.0), tất nhiên là hàm này luôn (not Nil) và được chấp nhận, thoát khỏi hàm.
Lần thứ 2 chạy lại lệnh, lúc này biến hs đã được gán kết quả từ lần đầu => biểu thức hs Not nil => thoát khỏi hàm Or và không có gì để bàn tiếp, hs cứ thế nhận giá trị lần đầu nhập vào
Ngoài ra bạn có thể viết theo cách CAD là nhận số lần trước nhập vào là mặc định cho mỗi lần ấn dấu cách, cái này bạn có thể tìm thấy trong hầu hết lisp trên 4room ^^
6 - Chú ý biến osmode khi sử dụng command, đã có bài Biến hệ thống trong CAD nói về biến này rất kỹ
  • 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


#4 hanam1210

hanam1210

    biết vẽ pline

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

Đã gửi 16 October 2011 - 01:27 PM

Vâng cảm ơn các anh trên diễn đàn. Thực ra e có biết gì về lisp mấy đâu. E copy đoạn mã ở lisp này lắp sang lisp kia thôi. Anh Doan Van Ha Sửa cho em rồi nhưng mà không đúng như yêu cầu. Qua chạy thử thì chiều dài line sai trong trường hợp -7<A<0,Em không tìm thấy đoạn code so sánh đó đâu nên không biết sửa thế nào. Viết kiểu if kia thì em còn hiểu được, chứ viết kiểu của a thì cao siêu em chịu chết. hức hức. Còn trường hợp A=0 thì ko vẽ, A=7 hay A = -7 thì không có cái đoạn ( phần nguyên của A/5 )*2
  • 0

#5 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 16 October 2011 - 03:14 PM

Vâng cảm ơn các anh trên diễn đàn. Thực ra e có biết gì về lisp mấy đâu. E copy đoạn mã ở lisp này lắp sang lisp kia thôi. Anh Doan Van Ha Sửa cho em rồi nhưng mà không đúng như yêu cầu. Qua chạy thử thì chiều dài line sai trong trường hợp -7<A<0,Em không tìm thấy đoạn code so sánh đó đâu nên không biết sửa thế nào. Viết kiểu if kia thì em còn hiểu được, chứ viết kiểu của a thì cao siêu em chịu chết. hức hức. Còn trường hợp A=0 thì ko vẽ, A=7 hay A = -7 thì không có cái đoạn ( phần nguyên của A/5 )*2

Tôi chỉ sửa theo y/c của bạn đặt ra, còn bạn muốn gì nữa trong lisp thi tôi đâu biết được mà biểu đúng với chả sai. Ít nhất ở cái chỗ sai ấy bạn cũng phải nêu lên được công thức toán học (chứ không cần lisp).
  • 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.


#6 npham

npham

    biết lệnh rotate

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

Đã gửi 16 October 2011 - 04:23 PM

Tôi chỉ sửa theo y/c của bạn đặt ra, còn bạn muốn gì nữa trong lisp thi tôi đâu biết được mà biểu đúng với chả sai. Ít nhất ở cái chỗ sai ấy bạn cũng phải nêu lên được công thức toán học (chứ không cần lisp).


Hôm nay cuối tuần mà bác ĐVH chưa chích vài ve hay sao mà nối cáu với e út thế :D
ý của e nó là có 4 TH, mà bác làm có 2 TH nên em í thắc mắc.
Có vẻ chủ thớt chỉ muốn có 1 cái lisp để ứng dụng chứ không có muốn n/c về lisp. Bác Ket mất công rồi.
  • 1

#7 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 16 October 2011 - 04:50 PM


Hôm nay cuối tuần mà bác ĐVH chưa chích vài ve hay sao mà nối cáu với e út thế Hình đã gửi
ý của e nó là có 4 TH, mà bác làm có 2 TH nên em í thắc mắc.
Có vẻ chủ thớt chỉ muốn có 1 cái lisp để ứng dụng chứ không có muốn n/c về lisp. Bác Ket mất công rồi.

Bạn và tôi đều ok một điều rằng: dù vất vả tí nhưng chủ thớt cứ nói y/c ra thì ai ai cũng muốn giúp. Ở đây, bạn ấy không nêu y/c cho trường hợp mà bạn ấy nói bị sai nên tôi botay, chứ nếu diễn giải rõ ra tôi sẽ giúp ngay. Với lại, Npham đọc kỹ thì 4 đ/k đó thực ra gom lại chỉ còn 2 đ/k thôi.
Chưa làm vài ve có nghĩa là sắp làm vai ve đấy!
  • 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.


#8 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 16 October 2011 - 04:54 PM

Có vẻ chủ thớt chỉ muốn có 1 cái lisp để ứng dụng chứ không có muốn n/c về lisp.

Sau bài trả lời của hanam1210 mình cũng lờ mờ hiểu ra như thế :)
  • 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


#9 npham

npham

    biết lệnh rotate

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

Đã gửi 16 October 2011 - 06:35 PM

Npham đọc kỹ thì 4 đ/k đó thực ra gom lại chỉ còn 2 đ/k thôi.


TH1: nếu A< -7, kc= A*Kđào +( phần nguyên của A/7 )*2
TH2: nếu -7 < A < 0, kc= A*Kđào
TH3: nếu 0<A< 7, kc= A*1.5
TH4: nếuA >7, kc= A*1.5 +( phần nguyên của A/5 )*2



Đúng là chưa đọc kỹ, mà chừ đọc kỹ thì vẫn thấy 4 TH, Bác gom kiểu chi hay rứa hè?
  • 0

#10 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 16 October 2011 - 08:33 PM

Đúng là chưa đọc kỹ, mà chừ đọc kỹ thì vẫn thấy 4 TH, Bác gom kiểu chi hay rứa hè?

Nói chung, y/c bên ngoài 1 kiểu, lisp 1 kiểu. Tôi căn cứ 4 đ/k của lisp để gom thành 2 thôi. Túm lại, thôi chắc đừng bàn tới nữa thì hay hơn. Tôi không có thói quen giúp 1 người mà họ không quan tâm. Chích rồi Npham ạ!
  • 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.


#11 npham

npham

    biết lệnh rotate

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

Đã gửi 16 October 2011 - 08:54 PM

Nói chung, y/c bên ngoài 1 kiểu, lisp 1 kiểu. Tôi căn cứ 4 đ/k của lisp để gom thành 2 thôi. Túm lại, thôi chắc đừng bàn tới nữa thì hay hơn. Tôi không có thói quen giúp 1 người mà họ không quan tâm. Chích rồi Npham ạ!


Hehe , đúng đó, có nhiều bạn lên nhờ, mình cặm cụi làm rồi post lên. Vậy mà chẳng thấy 1 lần quay lại nói 1 lời có dùng được hay chưa.
Mà thôi, viết lisp vì đam mê. Bác bỏ qua cho cái không vui.
Thân.
  • 1

#12 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 16 October 2011 - 09:31 PM

Hehe , đúng đó, có nhiều bạn lên nhờ, mình cặm cụi làm rồi post lên. Vậy mà chẳng thấy 1 lần quay lại nói 1 lời có dùng được hay chưa.
Mà thôi, viết lisp vì đam mê. Bác bỏ qua cho cái không vui.
Thân.

Đây là lisp viết theo diễn giải, không viết theo lisp bạn ấy post lên (vì mâu thuẩn nhau), chỉ có 1 thắc mắc: cái "A" để tính kc là A hay (abs A) nên tạm lấy (abs A) vậy, nếu không đúng thì sửa lại vậy.

(defun c:lo (/ kc ot)
(setq oldcm (getvar "cmdecho") oldos (getvar "osmode") )
(command "undo" "begin")
(if (not (tblsearch "layer" "GRID_TL")) (command "layer" "N" "GRID_TL" "S" "GRID_TL" "color" 3 "" ""))
(or *hsd* (setq *hsd* 1.0))
(setq hsd (getreal (strcat "\nHe so dao <" (rtos *hsd* 2) ">: ")))
(if (not hsd) (setq hsd *hsd*) (setq *hsd* hsd))
(while (setq p1 (getpoint "\nPick diem 1: "))
(setq p2 (getpoint p1 "\nPick dien 2: "))
(setq ot (read (substr (cdr (assoc 1 (entget (car (entsel "\n Chenh cao: "))))) 1)))
(setvar "cmdecho" 0) (setvar "osmode" 0)
(cond
((< ot -7) (setq kc (+ (* (abs ot) hsd) (* (fix (/ (abs ot) 7)) 2))))
((< -7 ot 0) (setq kc (* (abs ot) hsd)))
((< 0 ot 7) (setq kc (* ot 1.5)))
((> ot 7) (setq kc (+ (* ot 1.5) (* (fix (/ ot 5)) 2))))
(T (alert "Chu Thot khong yeu cau!") (exit)))
(command "line" p1 (polar p1 (angle p1 p2) kc) "")
(setvar "cmdecho" oldcm) (setvar "osmode" oldos))
(command "undo" "end")
(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.


#13 hanam1210

hanam1210

    biết vẽ pline

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

Đã gửi 17 October 2011 - 07:30 AM

Đây là lisp viết theo diễn giải, không viết theo lisp bạn ấy post lên (vì mâu thuẩn nhau), chỉ có 1 thắc mắc: cái "A" để tính kc là A hay (abs A) nên tạm lấy (abs A) vậy, nếu không đúng thì sửa lại vậy.

 (defun c:lo (/ kc ot) (setq oldcm (getvar "cmdecho") oldos (getvar "osmode") ) (command "undo" "begin") (if (not (tblsearch "layer" "GRID_TL")) (command "layer" "N" "GRID_TL" "S" "GRID_TL" "color" 3 "" "")) (or *hsd* (setq *hsd* 1.0)) (setq hsd (getreal (strcat "\nHe so dao <" (rtos *hsd* 2) ">: "))) (if (not hsd) (setq hsd *hsd*) (setq *hsd* hsd)) (while (setq p1 (getpoint "\nPick diem 1: ")) (setq p2 (getpoint p1 "\nPick dien 2: ")) (setq ot (read (substr (cdr (assoc 1 (entget (car (entsel "\n Chenh cao: "))))) 1))) (setvar "cmdecho" 0) (setvar "osmode" 0) (cond ((< ot -7) (setq kc (+ (* (abs ot) hsd) (* (fix (/ (abs ot) 7)) 2)))) ((< -7 ot 0) (setq kc (* (abs ot) hsd))) ((< 0 ot 7) (setq kc (* ot 1.5))) ((> ot 7) (setq kc (+ (* ot 1.5) (* (fix (/ ot 5)) 2)))) (T (alert "Chu Thot khong yeu cau!") (exit))) (command "line" p1 (polar p1 (angle p1 p2) kc) "") (setvar "cmdecho" oldcm) (setvar "osmode" oldos)) (command "undo" "end") (princ)) 


Lisp chạy đúng yêu cầu của em ban đầu rồi. Nhưng bi h khi chạy thực tế thì e mới thấy có điều chưa phù hợp, Em tạm chỉnh như sau nhưng nó chưa chạy. Bác chỉnh tiếp theo hướng đó giúp em. ( ở đây bác nhầm 1 chút là lúc thì dùng (* (fix (/ (abs ot) 7)) 2)))), lúc thì (* (( fix (/ ot 5)) 1) 2)))) ==> thống nhất dùng (* (( fix (/ ot 5)) 1) 2))))
Nhưng ở đây em muốn bớt đi 1 đơn vị của phần nguyên của ot/5, tức là cần cộng thêm vào chiều dài line 1 đoạn = ( (phần nguyên của A)/5 -1 )*2
(cái phần trừ đi 1 đơn vị e trừ thì nó hiểu thành giá trị âm nên trong code e ko biết trừ thế nào.

;; free lisp from cadviet.com
;;; this lisp was downloaded from http://www.cadviet.com/forum/index.php?showtopic=56841&pid=173673&st=0&#entry173673
(defun c:lo (/ kc ot)
(setq oldcm (getvar "cmdecho") oldos (getvar "osmode") )
(command "undo" "begin")
(if (not (tblsearch "layer" "GRID_TL")) (command "layer" "N" "GRID_TL" "S" "GRID_TL" "color" 3 "" ""))
(or *hsd* (setq *hsd* 1.0))
(setq hsd (getreal (strcat "\nHe so dao <" (rtos *hsd* 2) ">: ")))
(if (not hsd) (setq hsd *hsd*) (setq *hsd* hsd))
(while (setq p1 (getpoint "\nPick diem 1: "))
(setq p2 (getpoint p1 "\nPick dien 2: "))
(setq ot (read (substr (cdr (assoc 1 (entget (car (entsel "\n Chenh cao: "))))) 1)))
(setvar "cmdecho" 0) (setvar "osmode" 0)
(cond
((< ot -7) (setq kc (+ (* (abs ot) hsd) (* (fix (/ (abs ot) 7)) 2))))
((< -7 ot 0) (setq kc (* (abs ot) hsd)))
((= ot -7) (setq kc (* (abs ot) hsd)))
((< 0 ot 7) (setq kc (* ot 1.5)))
((> ot 7) (setq kc (+ (* ot 1.5) (* (( fix (/ ot 5)) 1) 2))))
((= ot 7) (setq kc (+ (* ot 1.5) (* (fix (/ ot 5)) 2))))
(command "line" p1 (polar p1 (angle p1 p2) kc) "")
(setvar "cmdecho" oldcm) (setvar "osmode" oldos))
(command "undo" "end")
(princ))


  • 0

#14 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 17 October 2011 - 08:47 AM

Lisp chạy đúng yêu cầu của em ban đầu rồi. Nhưng...

1). Cái chuyện abs hay không abs là do bạn nói không rõ.
2). Chia cho 7 hay chia cho 5 là do đề của bạn chứ tôi không sáng tác ra.
3). Còn 1 trường hợp ot=0 bạn chưa nói tới.
4). Lấy (fix (/ ot 5)) rồi trừ đi 1 hay lấy (/ (fix ot) 5) rồi trừ đi 1?
Tóm lại, bạn không cần sửa lisp mà chỉ cần diễn giải đầy đủ các trường hợp bằng lời và bằng công thức thì tôi mới có thể sửa được.
  • 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.


#15 hanam1210

hanam1210

    biết vẽ pline

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

Đã gửi 17 October 2011 - 09:11 AM

1). Cái chuyện abs hay không abs là do bạn nói không rõ.
2). Chia cho 7 hay chia cho 5 là do đề của bạn chứ tôi không sáng tác ra.
3). Còn 1 trường hợp ot=0 bạn chưa nói tới.
4). Lấy (fix (/ ot 5)) rồi trừ đi 1 hay lấy (/ (fix ot) 5) rồi trừ đi 1?
Tóm lại, bạn không cần sửa lisp mà chỉ cần diễn giải đầy đủ các trường hợp bằng lời và bằng công thức thì tôi mới có thể sửa được.

Em xin trả lời anh :
1- Lấy ABS
2- Chia cho 7
3- =0 thì ko có line nên ko cần
4-Lấy (fix (/ ot 5)) rồi trừ đi 1 sau đó nhân với 2 và cộng vào chiều dài line
  • 0

#16 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 17 October 2011 - 09:22 AM

Em xin trả lời anh :
1- Lấy ABS
2- Chia cho 7
3- =0 thì ko có line nên ko cần
4-Lấy (fix (/ ot 5)) rồi trừ đi 1 sau đó nhân với 2 và cộng vào chiều dài line

Chịu, không hiểu nổi bạn!
Ở trên thì nói chia cho 5, xuống đây nói chia cho 7 ở ý 2. rồi ý 4 thì lại chia cho 5.
Ở trên nói không có abs, xuống ý 1 nói lấy abs, qua ý 4 lại không có abs.
Thôi, bạn hãy diễn giải tất cả 6 trường hợp xãy ra bằng công thức toán học đi, chứ cứ trả lời mâu thuẩn nhau kiểu này thì bó tay thôi bạn ạ.
  • 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.


#17 hanam1210

hanam1210

    biết vẽ pline

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

Đã gửi 17 October 2011 - 09:36 AM

Chịu, không hiểu nổi bạn!
Ở trên thì nói chia cho 5, xuống đây nói chia cho 7 ở ý 2. rồi ý 4 thì lại chia cho 5.
Ở trên nói không có abs, xuống ý 1 nói lấy abs, qua ý 4 lại không có abs.
Thôi, bạn hãy diễn giải tất cả 6 trường hợp xãy ra bằng công thức toán học đi, chứ cứ trả lời mâu thuẩn nhau kiểu này thì bó tay thôi bạn ạ.

Hic. Em xin lỗi, cái đầu em post nhầm, em xin đính chính lại như sau :

TH1: nếu A< -7, kc= A*Kđào +( (phần nguyên của A/5) -1 )*2
TH2: nếu -7 =< A < 0, kc= A*Kđào
TH3: nếu 0=<A< =7, kc= A*1.5
TH4: nếuA >7, kc= A*1.5 +( (phần nguyên của A/5 -1 )*2
  • 0

#18 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 17 October 2011 - 09:37 AM

@hanam1210 : khó khăn để trình bày quá nhỉ :) ?
Ngoài ra, dòng này của bạn sai ngay cấu trúc của 1 phép tính thông thường,

(setq kc (+ (* ot 1.5) (* (( fix (/ ot 5)) 1) 2))))

Chí ít nó cũng phải có biểu thức gì chứ làm sao máy hiểu ((fix 1 số) 1) là việc gì ???
Theo ý của bạn đã nói thì nó phải là (- (fix (/ ot 5)) 1)
và mình thiết nghĩ là nếu bạn chịu khó đọc lại những lời mọi người nói thì đã không tốn thời gian của cả bạn và bác ĐVH đến vậy
  • 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


#19 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 17 October 2011 - 09:59 AM

Hic. Em xin lỗi, cái đầu em post nhầm, em xin đính chính lại như sau :

TH1: nếu A< -7, kc= A*Kđào +( (phần nguyên của A/5) -1 )*2
TH2: nếu -7 =< A < 0, kc= A*Kđào
TH3: nếu 0=<A< =7, kc= A*1.5
TH4: nếuA >7, kc= A*1.5 +( (phần nguyên của A/5 -1 )*2

Đây bạn!
P/S: đã sửa lúc 3h05

(defun c:lo (/ kc ot)
(setq oldcm (getvar "cmdecho") oldos (getvar "osmode") )
(command "undo" "begin")
(if (not (tblsearch "layer" "GRID_TL")) (command "layer" "N" "GRID_TL" "S" "GRID_TL" "color" 3 "" ""))
(or *hsd* (setq *hsd* 1.0))
(setq hsd (getreal (strcat "\nHe so dao <" (rtos *hsd* 2) ">: ")))
(if (not hsd) (setq hsd *hsd*) (setq *hsd* hsd))
(while (setq p1 (getpoint "\nPick diem 1: "))
(setq p2 (getpoint p1 "\nPick dien 2: "))
(setq ot (read (substr (cdr (assoc 1 (entget (car (entsel "\n Chenh cao: "))))) 1)))
(setvar "cmdecho" 0) (setvar "osmode" 0)
(cond
((< ot -7) (setq kc (+ (* (abs ot) hsd) (* (- (fix (/ (abs ot) 5)) 1) 2))))
((and (>= ot -7) (< ot 0)) (setq kc (* (abs ot) hsd)))
((<= 0 ot 7) (setq kc (* ot 1.5)))
((> ot 7) (setq kc (+ (* ot 1.5) (* (- (fix (/ ot 5)) 1) 2)))))
(command "line" p1 (polar p1 (angle p1 p2) kc) "")
(setvar "cmdecho" oldcm) (setvar "osmode" oldos))
(command "undo" "end")
(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.


#20 hanam1210

hanam1210

    biết vẽ pline

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

Đã gửi 17 October 2011 - 09:59 AM

@hanam1210 : khó khăn để trình bày quá nhỉ :) ?
Ngoài ra, dòng này của bạn sai ngay cấu trúc của 1 phép tính thông thường,

Chí ít nó cũng phải có biểu thức gì chứ làm sao máy hiểu ((fix 1 số) 1) là việc gì ???
Theo ý của bạn đã nói thì nó phải là (- (fix (/ ot 5)) 1)
và mình thiết nghĩ là nếu bạn chịu khó đọc lại những lời mọi người nói thì đã không tốn thời gian của cả bạn và bác ĐVH đến vậy

Vâng, Đúng là (- (fix (/ ot 5)) 1) , do em không biết diễn đạt. Bác ĐVH thông cảm nhé ! hic
  • 0