Đến nội dung


Hình ảnh
- - - - -

Hỏi: Cách nội suy tâm đường tròn 3D


  • Please log in to reply
58 replies to this topic

#21 NguyenNdait

NguyenNdait

    biết vẽ line

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

Đã gửi 14 December 2010 - 05:44 PM

Mình thử viết lại chương trình của ptbinh theo hướng :
Chọn tập hợp gồm n điểm (Ví dụ: Cho n = 5 ta có : tập hợp (1 2 3 4 5) phần tử. trong đó 1 = p1 2 = p2 ...)
Tìm tập hợp là tổ hợp chập 3 của n phần tử như trên
((123) (124) (125) (134) (135) (145) (234) (235) (245) (345))
Tìm tâm của các đtròn trên bằng cách giải hệ 2 phương trình đường tròn qua 3 điểm.
(1 ptrình đtròn đc làm cho suy biến bằng cách cho nó đi qua gốc tọa độ)
Vẽ pline qua các điiểm này.
Cụ thể như sau :
(defun chap3_lstp (lst / lst lst0 lst1 lst2 lstc p)
(setq lstc '() lst2 '() lst1 '())
(setq lst0 lst)
(foreach e lst
(setq lst1 (vl-remove e lst) lst (vl-remove e lst) p e)
(foreach e1 lst1
(setq lst2 (vl-remove e1 lst1) lst1 (vl-remove e1 lst1) p1 e1)
(foreach e2 lst2
(setq p2 e2)
(setq lstc (append (list (list p p1 p2)) lstc)))))
lstc
);end chap3
;-------------------------------------------
(defun c:noisuy (/ ssp i n e p lstpt)
(setq ssp (ssget (list (cons 0 "point"))))
(setq i 0 n (sslength ssp))
(while (< i n)
(setq e (ssname ssp i))
(setq p (cdr (assoc 10 (entget e))))
(if (not (member p lstpt))
(setq lstpt (append lstpt (list p)))
(setq ssp (vl-remove e ssp)));if
(setq i (1+ i)));while
(setq lpoint (chap3_lstp lstpt))
(setq i 0 lcen '())
(repeat (length lpoint)
(setq dtron (nth i lpoint))
(setq p1 (nth 0 dtron) p2 (nth 1 dtron) p3 (nth 2 dtron))
(setq A12 (angle p1 p2) A13 (angle p1 p3))
(if (or (equal A12 A13 0.000001) (equal A12 (/ A13 pi) 0.000001) (equal (/ A12 pi) A13 0.000001))
(setq i (1+ i)); 3 diem thang hang
(progn
(setq pt2 (mapcar '- p2 p1) pt3 (mapcar '- p3 p1))
(setq x2 (nth 0 pt2) y2 (nth 1 pt2) x3 (nth 0 pt3) y3 (nth 1 pt3))
(setq detA (- (* x2 y3) (* y2 x3)) m (* -0.5 (+ (expt x2 2) (expt y2 2))) n (* -0.5 (+ (expt x3 2) (expt y3 2))))
(setq a (/ (- (* m y3) (* n y2)) detA) b (/ (- (* n x2) (* m x3)) detA))
(setq lcen (append lcen (list (mapcar '+ p1 (list (- a) (- b) 0.0)))) i (1+ i)));progn
);if
);repeat
(entmake '((0 . "POLYLINE")) )
(setq i 0)
(repeat (length lcen)
(entmake (subst (list 10 (nth 0 (nth i lcen)) (nth 1 (nth i lcen)) (nth 2 (nth i lcen)))
'(10 1.0 1.0 0.0) '((0 . "VERTEX") (10 1.0 1.0 0.0))));entmake
(setq i (1+ i)));repeat
(entmake '((0 . "SEQEND")))
);defun
;------------------------------------------
@Duyminh86: Bạn chạy thử xem và cho ý kiến tiếp theo phải làm gì nhé . Hoặc giả mình không hiểu đc ý bạn ở chỗ nào ? Chúng ta sẽ cùng làm tiếp.
  • 1

Mầm non phường ba - Đây ta mầm cụ
Lãnh tụ non sông - Ngộ không.


#22 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 14 December 2010 - 07:05 PM

Chào cả nhà.
Chào bạn ptbinh
Mình góp ý bạn như sau :
- Thuật toán tính số đường tròn qua 3 điểm (Tổ hợp chập 3 của n phần tử) bằng cách lấy foreach 3 lần làm kết quả tăng 6 lần.
Do đó nếu cho chạy chương trình với khoảng n>100 phần tử thì lâu lắm.
- Đường tròn kết quả chỉ là một đtròn qua ít nhất 3 điểm trong tập hợp n điểm với tổng bình phương là nhỏ nhất trong tổng số các đường tròn khả dĩ.
- Mong muốn của bài toán là tìm được đường tròn có tâm là tâm của vùng tạo bởi tâm các đtròn đi qua 3 điểm trong n điểm.
TB: Mong chủ 2pic nói rõ thêm nữa về đề tài này. (Thuần hình học hay đây là một dạng bài toán tối ưu hóa theo pp bình phương tối thiểu)

Hề hề hề,
Đúng như bác góp ý, ở đây do mình chưa lập được thuật toán để xét tổ hợp nên mình chơi kiểu xét chỉnh hợp của nó. Về lý thuyết thì đúng là nó tăng hơn 6 lần so với số tổ hợp. (3!). Khi n càng tăng cao thì cái 6 lần này càng là con số nhỏ mà mình nghĩ là có thể chấp nhận được. Tỷ như giữa Tổ hợp chập 3 của 30 phần tử với chỉnh hợp chập 3 không xét lặp của 29 phần tử thì cái con số 6 lần này sẽ chả còn ý nghĩa nhiều lắm. Tức là vấn đề hạn chế chính là số điểm n chứ không phải là do cách tính chỉnh hợp hay tổ hợp bác ạ. Tất nhiên là về lý thuyết thì nó chưa tối ưu. Mình cũng đang nghĩ thuật toán để xét được theo các tổ hợp bác à. Hy vọng sẽ tìm ra được.
Do cái khái niệm tâm của vùng chưa được xác định nên mình cũng chưa rõ là cái bác định làm có đúng ý bạn chủ thớt hay không. Cái phương án của mình mình cũng đã giải thích ngay từ đầu là không phải đã đáp ứng đúng yêu cầu của bạn chủ thớt, mà chỉ cho một kết quả khả dĩ để nghiên cứu tiếp thôi. Vậy nên mình mới cho thông báo các thông số về đường tròn tìm được và tổng bình phương khoảng cách từ các điểm tới đường tròn này để bạn chủ thớt xem xét và quyết định phải làm gì tiếp theo bác ạ.
Rất vui vì được bác góp sức giải quyết bài toán khá hóc này.
Chúc bác luôn mạnh khỏe, vui vẻ và quan tâm tới diễn đàn....
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#23 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 14 December 2010 - 08:08 PM

Mình thử viết lại chương trình của ptbinh theo hướng :
Chọn tập hợp gồm n điểm (Ví dụ: Cho n = 5 ta có : tập hợp (1 2 3 4 5) phần tử. trong đó 1 = p1 2 = p2 ...)
Tìm tập hợp là tổ hợp chập 3 của n phần tử như trên
((123) (124) (125) (134) (135) (145) (234) (235) (245) (345))
Tìm tâm của các đtròn trên bằng cách giải hệ 2 phương trình đường tròn qua 3 điểm.
(1 ptrình đtròn đc làm cho suy biến bằng cách cho nó đi qua gốc tọa độ)
Vẽ pline qua các điiểm này.
Cụ thể như sau :

@Duyminh86: Bạn chạy thử xem và cho ý kiến tiếp theo phải làm gì nhé . Hoặc giả mình không hiểu đc ý bạn ở chỗ nào ? Chúng ta sẽ cùng làm tiếp.

Hề hề hề,
Chào bác NguyenNdait,
Cám ơn bác về cái thuật toán tìm tổ hợp của các đối tượng.
Trong phương án bác đưa ra, có nhẽ hay hơn là bác xác định các tâm vòng tròn bằng point thôi chứ chả cần thiết vẽ pline bác ạ. Tuy nhiên có một vấn đề nảy sinh là nếu bác lại định xác định tâm của các tâm này theo phương án trên thì rất gay. Bởi vì lúc này tập hợp các điểm tâm này sẽ tăng lên gấp bội so với tập hợp n điểm ban đầu. Và như vậy sẽ làm cho việc xác định tâm của nó thêm khó khăn.
Nên chăng từ các điểm tâm này bác tạo một đa giác lồi khép kín, từ đó bác có thể xác định trọng tâm của đa giác này và lấy đó làm tâm vùng?????

Vài ý kiến để bác tham khảo. Chúc bác vui.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#24 NguyenNdait

NguyenNdait

    biết vẽ line

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

Đã gửi 15 December 2010 - 08:59 AM

Hề hề hề,
Chào bác NguyenNdait,
Cám ơn bác về cái thuật toán tìm tổ hợp của các đối tượng.
Trong phương án bác đưa ra, có nhẽ hay hơn là bác xác định các tâm vòng tròn bằng point thôi chứ chả cần thiết vẽ pline bác ạ. Tuy nhiên có một vấn đề nảy sinh là nếu bác lại định các định tâm của các tâm này theo phương án trên thì rất gay. Bởi vì lúc này tập hợp các điểm tâm này sẽ tăng lên gấp bội so với tập hợp n điểm ban đầu. Và như vậy sẽ làm cho việc xác định tâm của nó thêm khó khăn.
Nên chăng từ các điểm tâm này bác tạo một đa giác lồi khép kín, từ đó bác có thể xác định trọng tâm của đa giác này và lấy đó làm tâm vùng?????

Vài ý kiến để bác tham khảo. Chúc bác vui.


Chào buổi sáng cả nhà.
Chương trình của mình đang còn dở dang. mình chỉ vẽ pl qua các tâm cho bạn Duyminh thấy rõ thêm về việc xác định tâm các đtròn theo như ý định ban đầu của topic. Các việc tiếp theo mình chưa rõ lắm.
Chứ nếu cứ lấy C(3,n) mãi thì số lượng tâm tăng lên vô cùng lớn.
@: Còn cái vụ bình phương tối thiểu gì đó thì mình không nắm được bao nhiêu đâu.
  • 0

Mầm non phường ba - Đây ta mầm cụ
Lãnh tụ non sông - Ngộ không.


#25 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 15 December 2010 - 06:47 PM

Chào bác Tue_NV,
Chân thành cám ơn sự chỉ bảo của bác. Mình cũng hơi dốt khi tạo list point mà không tạo list ename của nó bởi vì cái cần là list ename chứ không phải list point. Cái list point chỉ giúp mình loại các điểm trùng mà thôi. Mình đã bổ sung lại và lisp đã chạy tốt. Nó đây ạ: (trong lisp này mình có bổ sung thêm phần thông báo các giá trị xác định của đối tượng tìm được để người sử dụng cân nhắc lựa chọn và tạo thêm tâm của vòng tròn tìm được để người dùng có thể sử dụng tiếp theo)


(defun c:nst ( / olc lscir ssp ssp1 p1 p2 lst lst1 lst2 p cir tkc pt pc kc mau)
(command "undo" "be")
(setq oldos (getvar "osmode"))
(setq olc (getvar "cecolor"))
(setvar "osmode" 0)
(setq lscir (list))
(setq ssp (ssget (list (cons 0 "point"))))
;;;;;;;;(setq p1 (car (acet-geom-ss-extents ssp 0))
;;;;;;;; p2 (cadr (acet-geom-ss-extents ssp 0))
;;;;;;;:undecided:
(locpoint ssp)
;;;;;;;;(setq ssp1 (ssget "c" p1 p2 (list (cons 0 "point"))))
;;;;;;;;(setq lst (acet-ss-to-list ssp1) )
(foreach e lst
(setq lst1 (vl-remove e lst)
p (cdr (assoc 10 (entget e)))
)
(foreach e1 lst1
(setq lst2 (vl-remove e1 lst1)
p1 (cdr (assoc 10 (entget e1)))
)
(foreach e2 lst2
(setq p2 (cdr (assoc 10 (entget e2))))
(setvar "cecolor" "3")
(command "circle" "3p" p p1 p2 )
(setq ent (entlast))
(setq cir (vlax-ename->vla-object ent))
(setq tkc 0)
(foreach e lst
(setq pt (cdr (assoc 10 (entget e))))
(setq pc (vlax-curve-getClosestPointTo cir pt ))
(setq kc (distance pt pc))
(setq tkc (+ tkc (expt kc 2)))
)
(setq lscir (append lscir (list (list tkc ent))))
)
)
)
(setq lscir (vl-sort lscir '(lambda (x y) (< (car x) (car y)) )) )
(setq mau (car lscir))
(alert (strcat "\n Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la: " (rtos (car mau) 2 2)))
(setq po (cdr (assoc 10 (entget (cadr mau))))
R (cdr (assoc 40 (entget (cadr mau))))
)
(command "point" po "")
(alert (strcat "\n Vong tron tim duoc co toa do tam la:" "\n x = " (rtos (car po) 2 4)
"\n y = " (rtos (cadr po) 2 4) "\n z = " (rtos (caddr po) 2 4)
"\n Ban kinh la " (rtos R 2 4) ))
(foreach cir lscir
(if (/= (cadr cir) (cadr mau))
(command "erase" (cadr cir) "")
)
)
(setvar "osmode" oldos)
(setvar "cecolor" olc)
(command "undo" "e")
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun locpoint (ssp / lstpt i n e p)
(setq lstpt (list)
lst (list)
)
(if ssp
(progn
(setq i 0
n (sslength ssp)
)
(while (< i n)
(setq e (ssname ssp i))
(setq p (cdr (assoc 10 (entget e))))
(if (not (member p lstpt))
(progn
(setq lstpt (append lstpt (list p)))
(setq lst (append lst (list e)))
)
(command "erase" e "")
)
(setq i (1+ i))
)
)
)
lst
)

Không có chi đâu bác Bình.
Em có ý kiến như thế này để cải thiện tốc độ của Lisp. Ta hạn chế việc vòng lặp tìm biến tkc (Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la) và đồng thời hạn chế được số phần tử trong tâp lscir
Bác xây dựng thử nhé :

1. Nếu đường tròn mà Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la: 0 thì đường tròn đó là duy nhất

2. Tìm cách Xác định khoảng cách giữa 2 điểm lớn nhất gọi là Dmax. Đường tròn tìm được là đường tròn có bán kính không được lớn hơn Dmax/2.

=> Do đó khi mà bác vẽ đường tròn thì xác định luôn bán kính R của nó. Xem bán kính R có bé hơn Dmax/2 không?
Nếu R<= Dmax/2 thì giữ lại để xác định tổng khoảng cách bình phương và làm công việc tiếp theo.....
Nếu R> Dmax/2 thì xóa luôn đường tròn và vì thế ta không xác định biến tkc chẳng đưa vào tập lscir để tăng tốc độ của Lisp

3. Nếu 3 điểm thẳng hàng thì không thể nào xây dựng được đường tròn nào cả. Nếu 3 điểm thẳng hàng thì Lisp của bác chạy sai vì bác chưa xét đến trường hợp này

Chuúc bác vui
  • 1

#26 NguyenNdait

NguyenNdait

    biết vẽ line

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

Đã gửi 16 December 2010 - 11:11 AM

Không có chi đâu bác Bình.
Em có ý kiến như thế này để cải thiện tốc độ của Lisp. Ta hạn chế việc vòng lặp tìm biến tkc (Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la) và đồng thời hạn chế được số phần tử trong tâp lscir
Bác xây dựng thử nhé :

1. Nếu đường tròn mà Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la: 0 thì đường tròn đó là duy nhất

2. Tìm cách Xác định khoảng cách giữa 2 điểm lớn nhất gọi là Dmax. Đường tròn tìm được là đường tròn có bán kính không được lớn hơn Dmax/2.

=> Do đó khi mà bác vẽ đường tròn thì xác định luôn bán kính R của nó. Xem bán kính R có bé hơn Dmax/2 không?
Nếu R<= Dmax/2 thì giữ lại để xác định tổng khoảng cách bình phương và làm công việc tiếp theo.....
Nếu R> Dmax/2 thì xóa luôn đường tròn và vì thế ta không xác định biến tkc chẳng đưa vào tập lscir để tăng tốc độ của Lisp

3. Nếu 3 điểm thẳng hàng thì không thể nào xây dựng được đường tròn nào cả. Nếu 3 điểm thẳng hàng thì Lisp của bác chạy sai vì bác chưa xét đến trường hợp này

Chuúc bác vui


Thật ra vấn đề làm cho lsp chậm chạp và ì ạch nhất đó chính là việc gọi các hàm command của CAD.
Để tăng tốc độ của chương trình lsp cần hạn chế việc gọi lại các hàm command của CAD, thay vào đó là entmake các đối tượng muốn tạo.
TB : mà sao không thấy chủ topic đâu cả vậy ta ?
  • 0

Mầm non phường ba - Đây ta mầm cụ
Lãnh tụ non sông - Ngộ không.


#27 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 16 December 2010 - 04:28 PM

Không có chi đâu bác Bình.
Em có ý kiến như thế này để cải thiện tốc độ của Lisp. Ta hạn chế việc vòng lặp tìm biến tkc (Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la) và đồng thời hạn chế được số phần tử trong tâp lscir
Bác xây dựng thử nhé :

1. Nếu đường tròn mà Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la: 0 thì đường tròn đó là duy nhất

2. Tìm cách Xác định khoảng cách giữa 2 điểm lớn nhất gọi là Dmax. Đường tròn tìm được là đường tròn có bán kính không được lớn hơn Dmax/2.

=> Do đó khi mà bác vẽ đường tròn thì xác định luôn bán kính R của nó. Xem bán kính R có bé hơn Dmax/2 không?
Nếu R<= Dmax/2 thì giữ lại để xác định tổng khoảng cách bình phương và làm công việc tiếp theo.....
Nếu R> Dmax/2 thì xóa luôn đường tròn và vì thế ta không xác định biến tkc chẳng đưa vào tập lscir để tăng tốc độ của Lisp

3. Nếu 3 điểm thẳng hàng thì không thể nào xây dựng được đường tròn nào cả. Nếu 3 điểm thẳng hàng thì Lisp của bác chạy sai vì bác chưa xét đến trường hợp này

Chuúc bác vui

Chào bác Tue_NV,
Rất cám ơn bác đã góp ý.
Ý 1 và ý 3 của bác mình đã bổ sung được vào lisp và có thể nói là khá yên tâm.
Tuy nhiên ở ý 2, việc khống chế giá trị của bán kính vòng tròn phải nhỏ hơn Dmax/2 theo mình là chưa hợp lý lắm vì thực tế với một tam giác đều hay ngũ giác đều thì bán kính vòng tròn ngoại tiếp của nó lớn hơn 1/2 cái đường chéo của nó bác ạ, (với tam giác đều thì là cạnh). Vì thế theo mình nghĩ thì việc khống chế bán kính này nên lấy ở giá trị (Dmax / (sqrt 2)) có nhẽ sẽ hợp lý hơn bác ạ.
Vì thế mình đã bổ sung thành cái lisp như sau, rất mong các bác góp ý để hoàn thiện nó.

(defun c:nst ( / olc lscir ssp ssp1 p1 p2 lst lst1 lst2 p cir tkc pt pc kc mau d1 d2 d3 ra dm lst0)
(command "undo" "be")
(setq oldos (getvar "osmode"))
(setq olc (getvar "cecolor"))
(setvar "osmode" 0)
(setq lscir (list))
(setq ssp (ssget (list (cons 0 "point"))))
;;;;;;;;(setq p1 (car (acet-geom-ss-extents ssp 0))
;;;;;;;; p2 (cadr (acet-geom-ss-extents ssp 0))
;;;;;;;:undecided:
(locpoint ssp)
;;;;;;;;(setq ssp1 (ssget "c" p1 p2 (list (cons 0 "point"))))
;;;;;;;;(setq lst (acet-ss-to-list ssp1) )
(setq lst0 lst)
(setq dm (dmax lst0))
(foreach e lst
(setq lst1 (vl-remove e lst)
lst (vl-remove e lst)
p (cdr (assoc 10 (entget e)))
)
(foreach e1 lst1
(setq lst2 (vl-remove e1 lst1)
lst1 (vl-remove e1 lst1)
p1 (cdr (assoc 10 (entget e1)))
;;;;;;g1 (angle p p1)
d1 (distance p p1)
)
(foreach e2 lst2
(setq p2 (cdr (assoc 10 (entget e2))))
(setvar "cecolor" "3")
(setq ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;g2 (angle p1 p2)
d2 (distance p1 p2)
d3 (distance p2 p)
)
(if (and (< d1 (+ d2 d3)) (< d2 (+ d1 d3)) (< d3 (+ d1 d2)))
(command "circle" "3p" p p1 p2 )
)
(setq ent (entlast))
(setq cir (vlax-ename->vla-object ent))
(setq tkc 0)
(setq ra (cdr (assoc 40 (entget ent))))
(if (<= ra (/ dm (sqrt 2)) )
(progn
(foreach e lst0
(setq pt (cdr (assoc 10 (entget e))))
(setq pc (vlax-curve-getClosestPointTo cir pt ))
(setq kc (distance pt pc))
(setq tkc (+ tkc (expt kc 2)))

)
(if (= tkc 0)
(progn
(setq mau (list tkc ent))
(ketthuc)
)
(setq lscir (append lscir (list (list tkc ent))))
)
)
(command "erase" ent "")
)
)
)
)
(setq lscir (vl-sort lscir '(lambda (x y) (< (car x) (car y)) )) )
(setq mau (car lscir))
(ketthuc)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ketthuc ()
(alert (strcat "\n Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la: " (rtos (car mau) 2 2)))
(setq po (cdr (assoc 10 (entget (cadr mau))))
R (cdr (assoc 40 (entget (cadr mau))))
)
(command "point" po "")
(alert (strcat "\n Vong tron tim duoc co toa do tam la:" "\n x = " (rtos (car po) 2 4)
"\n y = " (rtos (cadr po) 2 4) "\n z = " (rtos (caddr po) 2 4)
"\n Ban kinh la " (rtos R 2 4) ))
(foreach cir lscir
(if (/= (cadr cir) (cadr mau))
(command "erase" (cadr cir) "")
)
)
(setvar "osmode" oldos)
(setvar "cecolor" olc)
(command "undo" "e")
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun locpoint (ssp / lstpt i n e p)
(setq lstpt (list)
lst (list)
)
(if ssp
(progn
(setq i 0
n (sslength ssp)
)
(while (< i n)
(setq e (ssname ssp i))
(setq p (cdr (assoc 10 (entget e))))
(if (not (member p lstpt))
(progn
(setq lstpt (append lstpt (list p)))
(setq lst (append lst (list e)))
)
(command "erase" e "")
)
(setq i (1+ i))
)
)
)
lst
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
Xac dinh khoang cach lon nhat giua cac diem trong danh sach ename cua cac diem duoc chon

(defun dmax (lstp / lstp1 lstp0 lsdc p p1 d )
(setq lstp0 lstp)
(setq lsdc (list))
(foreach e lstp
(setq lstp1 (vl-remove e lstp)
lstp (vl-remove e lstp)
p (cdr (assoc 10 (entget e)))
)
(foreach e1 lstp1
(setq p1 (cdr (assoc 10 (entget e1)))
d (distance p p1)
lsdc (append lsdc (list d))
)
)
)
(setq lsdc (vl-sort lsdc '(lambda (x y) (>= x y))))
(setq dma (car lsdc))
dma
)


@Bác NguyenNdait,
Việc dùng hàm entmake trong trường hợp này sẽ phải lập công thức tính toán tọa độ tâm và bán kính của vòng tròn qua ba điểm cho trước. Về Lý thuyết hoàn toàn khả thi song thực tế ngồi mò mẫm lại cái đám công thức phổ thông này cũng hơi đau đầu bác ạ vả cũng khá dài dòng. Việc này mong bác thư thư cho một chút để mình còn mò mẫm chứ chưa thử ngay được bác ạ.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#28 DuongTrungHuy

DuongTrungHuy

    biết lệnh copy

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

Đã gửi 16 December 2010 - 04:49 PM

Việc dùng hàm entmake trong trường hợp này sẽ phải lập công thức tính toán tọa độ tâm và bán kính của vòng tròn qua ba điểm cho trước. Về Lý thuyết hoàn toàn khả thi song thực tế ngồi mò mẫm lại cái đám công thức phổ thông này cũng hơi đau đầu bác ạ vả cũng khá dài dòng. Việc này mong bác thư thư cho một chút để mình còn mò mẫm chứ chưa thử ngay được bác ạ.

Để tìm vòng tròn qua 1 danh sách 3 điểm Bạn dùng thử đoạn sau:

(defun tamO_nt(ds3diem / xA yA xB yB xC yC)
(setq xA (car (nth 0 ds3diem)) yA (cadr (nth 0 ds3diem))
xB (car (nth 1 ds3diem)) yB (cadr (nth 1 ds3diem))
xC (car (nth 2 ds3diem)) yC (cadr (nth 2 ds3diem))
)
(Cond
((< (abs(- xA xB)) 0.0000001)(setq xx xA xA xC xC xx xx yA yA yC yC xx))
((< (abs(- xA xC)) 0.0000001)(setq xx xA xA xB xB xx xx yA yA yB yB xx))
)
(setq so1 (/ (+ (- (* xB xB)(* xA xA)) (- (* yB yB)(* yA yA))) (- xB xA))
so2 (/ (+ (- (* xC xC)(* xA xA)) (- (* yC yC)(* yA yA))) (- xC xA))
so3 (/ (- yB yA) (- xB xA))
so4 (/ (- yC yA) (- xC xA))
tamO_y (/ (- so1 so2)(- so3 so4) 2.0)
tamO_x (- (/ so1 2.0) (* tamO_y so3))
tamO (list tamo_x tamo_y)
bkR (distance tamO (list xC yC))
)
)


Bạn viết thêm đoạn loại bỏ khi 3 điểm đó thẳng hàng.Giá trị trả về là điểm tamO và BkR
  • 1

#29 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 16 December 2010 - 06:51 PM

Để tìm vòng tròn qua 1 danh sách 3 điểm Bạn dùng thử đoạn sau:

(defun tamO_nt(ds3diem / xA yA xB yB xC yC)
(setq xA (car (nth 0 ds3diem)) yA (cadr (nth 0 ds3diem))
xB (car (nth 1 ds3diem)) yB (cadr (nth 1 ds3diem))
xC (car (nth 2 ds3diem)) yC (cadr (nth 2 ds3diem))
)
(Cond
((< (abs(- xA xB)) 0.0000001)(setq xx xA xA xC xC xx xx yA yA yC yC xx))
((< (abs(- xA xC)) 0.0000001)(setq xx xA xA xB xB xx xx yA yA yB yB xx))
)
(setq so1 (/ (+ (- (* xB xB)(* xA xA)) (- (* yB yB)(* yA yA))) (- xB xA))
so2 (/ (+ (- (* xC xC)(* xA xA)) (- (* yC yC)(* yA yA))) (- xC xA))
so3 (/ (- yB yA) (- xB xA))
so4 (/ (- yC yA) (- xC xA))
tamO_y (/ (- so1 so2)(- so3 so4) 2.0)
tamO_x (- (/ so1 2.0) (* tamO_y so3))
tamO (list tamo_x tamo_y)
bkR (distance tamO (list xC yC))
)
)
Bạn viết thêm đoạn loại bỏ khi 3 điểm đó thẳng hàng.Giá trị trả về là điểm tamO và BkR

Chào các bác,
Đây là cái lisp mình sửa lại bỏ các hàm gọi command của CAD và thay bằng các hàm trong lisp. Mình sử dụng sự trợ giúp của bác Dương Trung Huy để lấy tâm và bán kính của vòng tròn đi qua ba điểm không thẳng hàng

(defun c:nst ( / olc lscir ssp ssp1 p1 p2 lst lst1 lst2 p cir tkc pt pc kc mau d1 d2 d3 ra dm lst0)
(command "undo" "be")
(setq oldos (getvar "osmode"))
(setq olc (getvar "cecolor"))
(setvar "osmode" 0)
(setq lscir (list))
(setq ssp (ssget (list (cons 0 "point"))))
;;;;;;;;(setq p1 (car (acet-geom-ss-extents ssp 0))
;;;;;;;; p2 (cadr (acet-geom-ss-extents ssp 0))
;;;;;;;:undecided:
(locpoint ssp)
;;;;;;;;(setq ssp1 (ssget "c" p1 p2 (list (cons 0 "point"))))
;;;;;;;;(setq lst (acet-ss-to-list ssp1) )
(setq lst0 lst)
(setq dm (dmax lst0))
(setvar "cecolor" "3")
(foreach e lst
(setq lst1 (vl-remove e lst)
lst (vl-remove e lst)
p (cdr (assoc 10 (entget e)))
)
(foreach e1 lst1
(setq lst2 (vl-remove e1 lst1)
lst1 (vl-remove e1 lst1)
p1 (cdr (assoc 10 (entget e1)))
d1 (distance p p1)
)
(foreach e2 lst2
(setq p2 (cdr (assoc 10 (entget e2))))
(setq d2 (distance p1 p2)
d3 (distance p2 p)
)
(if (and (< d1 (+ d2 d3)) (< d2 (+ d1 d3)) (< d3 (+ d1 d2)))
;;;;;;;;(command "circle" "3p" p p1 p2 )
(progn
(setq lst3d (list p p1 p2))
(tamo_nt lst3d )
(entmake (list (cons 0 "circle") (cons 10 tamo) (cons 40 bkR)))
)
)
(setq ent (entlast))
(setq cir (vlax-ename->vla-object ent))
(setq tkc 0)
(setq ra (cdr (assoc 40 (entget ent))))
(if (<= ra (/ dm (sqrt 2)) )
(progn
(foreach e lst0
(setq pt (cdr (assoc 10 (entget e))))
(setq pc (vlax-curve-getClosestPointTo cir pt ))
(setq kc (distance pt pc))
(setq tkc (+ tkc (expt kc 2)))

)
(if (= tkc 0)
(progn
(setq mau (list tkc ent))
(ketthuc)
)
(setq lscir (append lscir (list (list tkc ent))))
)
)
;;;;;;(command "erase" ent "")
(entdel ent)
)
)
)
)
(setq lscir (vl-sort lscir '(lambda (x y) (< (car x) (car y)) )) )
(setq mau (car lscir))
(ketthuc)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ketthuc ()
(alert (strcat "\n Tong binh phuong khoang cach tu cac diem toi vong tron tim duoc la: " (rtos (car mau) 2 4)))
(setq po (cdr (assoc 10 (entget (cadr mau))))
R (cdr (assoc 40 (entget (cadr mau))))
)
(command "point" po "")
(alert (strcat "\n Vong tron tim duoc co toa do tam la:" "\n x = " (rtos (car po) 2 4)
"\n y = " (rtos (cadr po) 2 4) "\n z = " (rtos (caddr po) 2 4)
"\n Ban kinh la " (rtos R 2 4) ))
(foreach cir lscir
(if (/= (cadr cir) (cadr mau))
;;;;;;(command "erase" (cadr cir) "")
(entdel (cadr cir))
)
)
(setvar "osmode" oldos)
(setvar "cecolor" olc)
(command "undo" "e")
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun locpoint (ssp / lstpt i n e p)
(setq lstpt (list)
lst (list)
)
(if ssp
(progn
(setq i 0
n (sslength ssp)
)
(while (< i n)
(setq e (ssname ssp i))
(setq p (cdr (assoc 10 (entget e))))
(if (not (member p lstpt))
(progn
(setq lstpt (append lstpt (list p)))
(setq lst (append lst (list e)))
)
;;;;;(command "erase" e "")
(entdel e)
)
(setq i (1+ i))
)
)
)
lst
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;
;;;;;Xac dinh khoang cach lon nhat giua cac diem trong danh sach ename cua cac diem duoc chon

(defun dmax (lstp / lstp1 lstp0 lsdc p p1 d )
(setq lstp0 lstp)
(setq lsdc (list))
(foreach e lstp
(setq lstp1 (vl-remove e lstp)
lstp (vl-remove e lstp)
p (cdr (assoc 10 (entget e)))
)
(foreach e1 lstp1
(setq p1 (cdr (assoc 10 (entget e1)))
d (distance p p1)
lsdc (append lsdc (list d))
)
)
)
(setq lsdc (vl-sort lsdc '(lambda (x y) (>= x y))))
(setq dma (car lsdc))
dma
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;
;;;;;;Xac dinh tam va ban kinh vong tron qua 3 diem

(defun tamO_nt (ds3diem / xA yA xB yB xC yC)
(setq xA (car (nth 0 ds3diem)) yA (cadr (nth 0 ds3diem))
xB (car (nth 1 ds3diem)) yB (cadr (nth 1 ds3diem))
xC (car (nth 2 ds3diem)) yC (cadr (nth 2 ds3diem))
)
(Cond
((< (abs(- xA xB)) 0.0000001)(setq xx xA xA xC xC xx xx yA yA yC yC xx))
((< (abs(- xA xC)) 0.0000001)(setq xx xA xA xB xB xx xx yA yA yB yB xx))
)
(setq so1 (/ (+ (- (* xB xB)(* xA xA)) (- (* yB yB)(* yA yA))) (- xB xA))
so2 (/ (+ (- (* xC xC)(* xA xA)) (- (* yC yC)(* yA yA))) (- xC xA))
so3 (/ (- yB yA) (- xB xA))
so4 (/ (- yC yA) (- xC xA))
tamO_y (/ (- so1 so2)(- so3 so4) 2.0)
tamO_x (- (/ so1 2.0) (* tamO_y so3))
tamO (list tamo_x tamo_y)
bkR (distance tamO (list xC yC))
)
)


Kết quả mình có vài nhận xét như sau:
1/- Quả nhiên là lisp chạy nhanh hơn hẳn về tốc độ.
2/- Khi số lượng đối tượng đủ lớn, lisp chạy bị lỗi xóa không hết các vòng tròn cần xóa bởi lệnh (entdel (cadr cir)) thay vì (command "erase" (cadr cir) "")
3/- Khi chạy lisp các vòng tròn được tạo bởi hàm enmake xuất hiện chỉ sau khi có hàm thông báo alert, khác với khi dùng lệnh command "circle" của CAD.
Khi đó các vòng tròn xuất hiện lần lượt trứớc khi bảng thông báo alert xuất hiện. Điều này chừng nào đó gây khó hiểu cho người dùng.
4/- Kết luận của mình, có nhẽ chậm mà chắc, cứ nên xài thằng command của CAD có nhẽ nó ổn định và theo đúng ý đồ của người viết hơn các bác nhể.
5/- Các bác có thể giải thích được vì sao có những hiện tượng như vầy hay không, phải chăng các hàm lisp nó chạy nhanh quá nên bỏ sót lỗi????
Chúc các bác luôn vui.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#30 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 17 December 2010 - 09:27 AM

1 .Để tìm vòng tròn qua 1 danh sách 3 điểm Bạn dùng thử đoạn sau:

(defun tamO_nt(ds3diem / xA yA xB yB xC yC)
(setq xA (car (nth 0 ds3diem)) yA (cadr (nth 0 ds3diem))
xB (car (nth 1 ds3diem)) yB (cadr (nth 1 ds3diem))
xC (car (nth 2 ds3diem)) yC (cadr (nth 2 ds3diem))
)
(Cond
((< (abs(- xA xB)) 0.0000001)(setq xx xA xA xC xC xx xx yA yA yC yC xx))
((< (abs(- xA xC)) 0.0000001)(setq xx xA xA xB xB xx xx yA yA yB yB xx))
)
(setq so1 (/ (+ (- (* xB xB)(* xA xA)) (- (* yB yB)(* yA yA))) (- xB xA))
so2 (/ (+ (- (* xC xC)(* xA xA)) (- (* yC yC)(* yA yA))) (- xC xA))
so3 (/ (- yB yA) (- xB xA))
so4 (/ (- yC yA) (- xC xA))
tamO_y (/ (- so1 so2)(- so3 so4) 2.0)
tamO_x (- (/ so1 2.0) (* tamO_y so3))
tamO (list tamo_x tamo_y)
bkR (distance tamO (list xC yC))
)
)
2 .Bạn viết thêm đoạn loại bỏ khi 3 điểm đó thẳng hàng.Giá trị trả về là điểm tamO và BkR

Ý 1 và ý 2 của Bác DuongTrungHuy có thể sử dụng qua code sau
Lisp tìm tâm và bán kính đường tròn qua 3 điểm không thẳng hàng. Kiểm tra luôn 3 điểm thẳng hàng thì không xây dựng được đường tròn (không tìm được tâm và bán kính
(defun CirC(A D C / M1 M2 M11 M21)
(setq M1 (acet-geom-midpoint A D))
(setq M2 (acet-geom-midpoint C D))
(setq M11 (polar M1 (+ (angle A D) (/ pi 2)) 100))
(setq M21 (polar M2 (+ (angle C D) (/ pi 2)) 100))
(if (setq tam (inters M1 M11 M2 M21 nil))
(setq R (distance tam A))
(alert "3 diem thang hang")
)
)
Tâm của đường tròn đi qua 3 điểm là giao điểm của 3 đường trung trực (của 3 cạnh). Ta chỉ cần tìm giao điểm của 2 đường trung trực là đủ, đường trung trực còn lại tất yếu sẽ đi qua tâm. Nếu 2 đường trung trực song song (không tìm được giao điểm) -> Chứng tỏ 3 điểm thẳng hàng. Ý tưởng đã được Tue_NV trình bày trên code trên

@Bác PhamThanhBinh : Bác có thể sử dụng code của Tue_NV để kiểm tra 3 điểm thẳng hàng và đồng thời tìm tâm và bán kính của đường tròn đi qua 3 điểm không thẳng hàng luôn
Em dạo này bận quá. Khi rãnh để em đọc code của bác và chạy thử mới góp ý được
Chúc bác sức khoẻ
  • 0

#31 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 17 December 2010 - 02:51 PM

Ý 1 và ý 2 của Bác DuongTrungHuy có thể sử dụng qua code sau
Lisp tìm tâm và bán kính đường tròn qua 3 điểm không thẳng hàng. Kiểm tra luôn 3 điểm thẳng hàng thì không xây dựng được đường tròn (không tìm được tâm và bán kính

(defun CirC(A D C / M1 M2 M11 M21)
(setq M1 (acet-geom-midpoint A D))
(setq M2 (acet-geom-midpoint C D))
(setq M11 (polar M1 (+ (angle A D) (/ pi 2)) 100))
(setq M21 (polar M2 (+ (angle C D) (/ pi 2)) 100))
(if (setq tam (inters M1 M11 M2 M21 nil))
(setq R (distance tam A))
(alert "3 diem thang hang")
)
)
Tâm của đường tròn đi qua 3 điểm là giao điểm của 3 đường trung trực (của 3 cạnh). Ta chỉ cần tìm giao điểm của 2 đường trung trực là đủ, đường trung trực còn lại tất yếu sẽ đi qua tâm. Nếu 2 đường trung trực song song (không tìm được giao điểm) -> Chứng tỏ 3 điểm thẳng hàng. Ý tưởng đã được Tue_NV trình bày trên code trên

@Bác PhamThanhBinh : Bác có thể sử dụng code của Tue_NV để kiểm tra 3 điểm thẳng hàng và đồng thời tìm tâm và bán kính của đường tròn đi qua 3 điểm không thẳng hàng luôn
Em dạo này bận quá. Khi rãnh để em đọc code của bác và chạy thử mới góp ý được
Chúc bác sức khoẻ

Chào bác Tue_NV,
Mình đã thay cái lisp của bác vào vị trí cái lisp của bác Dương Trung Huy, song kết quả cũng tương tự như bài post trước bác ạ. Nghĩa là khi tăng số điểm lên một giá trị nào đó thì cả hai đều xuất hiện hiện tượng xóa không hết các vòng tròn không được chọn. Khi thay hàm (command "erase" (cadr cir)) vào hàm (entdel (cadr cir)) thì lisp chạy chậm lại nhưng không bỏ sót nữa bác ạ.
Một lỗi nữa là không rõ tại sao mình đã loại trường hợp 3 điểm thẳng hàng bằng hàm (if (and (< d1 (+ d3 d2)) (< d2 (+ d1 d3)) (< d3 (+ d1 d2))) .....)
Vậy mà khi chạy lisp thỉnh thoảng vẫn xuất hiện thông bào " 3 điểm thẳng hàng" . Tức là việc loại trừ của mình chưa triệt để.
Phải chăng đó là nhựơc điểm của lisp khi lấy khoảng cách bằng hàm (distance .... ) không được chính xác hả bác????
Chúc bác khỏe và thuận lợi trong công việc để rảnh thời gian, giúp đỡ mọi người được nhiều hơn.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#32 duyminh86

duyminh86

    biết pan

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

Đã gửi 18 December 2010 - 08:09 AM

cảm ơn bác phamthanhbinh chương trình Lisp này của bác rất tuyệt, nhưng với phương pháp này chắc sẽ khó để làm trên 3D. Bác có phương pháp nào mà có thể làm trên 3D được ko.
Mong bác và mọi người ngâm cứu giúp em thực hiện trên 3D với nhé, vì công việc nó đòi hỏi trên 3D mà

em cám ơn các bác rất nhiều, các bác thật nhiệt tình, chúc cho cadviet phát triển mạnh
  • 0

#33 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 18 December 2010 - 09:44 AM

cảm ơn bác phamthanhbinh chương trình Lisp này của bác rất tuyệt, nhưng với phương pháp này chắc sẽ khó để làm trên 3D. Bác có phương pháp nào mà có thể làm trên 3D được ko.
Mong bác và mọi người ngâm cứu giúp em thực hiện trên 3D với nhé, vì công việc nó đòi hỏi trên 3D mà

em cám ơn các bác rất nhiều, các bác thật nhiệt tình, chúc cho cadviet phát triển mạnh

Hề hề hề,
Thực ra thì với cách tổ hợp 3 điểm này thì với cả 3D nó cũng như rứa. Chỉ có điều các mặt phẳng tạo bởi 3 điểm này không phải lúc nào cũng thỏa mãn là nghiêng với mặt phẳng vuông góc đường tâm trụ một góc nằm trong giới hạn như bạn yêu cầu mà thôi. Như vậy có nhẽ phải tính đến việc xét góc của mặt phẳng tạo bởi 3 điểm với mặt phảng cho trước bạn ạ.
Chắc chắn các bác trên diễn đàn sẽ có võ trị được nó, bạn yên tâm chờ đợi nhé....
Hề hề hề.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#34 NguyenNdait

NguyenNdait

    biết vẽ line

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

Đã gửi 18 December 2010 - 01:15 PM

Hề hề hề,
Thực ra thì với cách tổ hợp 3 điểm này thì với cả 3D nó cũng như rứa. Chỉ có điều các mặt phẳng tạo bởi 3 điểm này không phải lúc nào cũng thỏa mãn là nghiêng với mặt phẳng vuông góc đường tâm trụ một góc nằm trong giới hạn như bạn yêu cầu mà thôi. Như vậy có nhẽ phải tính đến việc xét góc của mặt phẳng tạo bởi 3 điểm với mặt phảng cho trước bạn ạ.
Chắc chắn các bác trên diễn đàn sẽ có võ trị được nó, bạn yên tâm chờ đợi nhé....
Hề hề hề.

Mình viết ctrình này như sau :
;; free lisp from cadviet.com
(defun chap3_lstp (lst / lst lst0 lst1 lst2 lstc p)
  (setq lstc '() lst2 '() lst1 '())
  (setq lst0 lst)
(foreach e lst
      (setq lst1 (vl-remove e lst) lst (vl-remove e lst) p e)              
      (foreach e1 lst1      
            (setq lst2 (vl-remove e1 lst1) lst1 (vl-remove e1 lst1) p1 e1)                  
            (foreach e2 lst2        
                   (setq p2 e2)
                   (setq lstc (append (list (list p p1 p2)) lstc)))))
  lstc
  );end chap3
;-------------------------------------------
(defun c:noisuy ()
  (setq ssp (ssget (list (cons 0 "point"))))
  (setq i 0 n (sslength ssp) lstpt '())
  (while (< i n)
    (setq p (cdr (assoc 10 (entget (ssname ssp i)))))
    (if (not (member p lstpt))
      (setq lstpt (append lstpt (list p)))
      (setq ssp (vl-remove e ssp)));if
    (setq i (1+ i)));while
  (setq lpoint (chap3_lstp lstpt))
  (setq i 0 lcen '() lsum '() lrad '())
  (repeat (length lpoint)
    (setq dtron (nth i lpoint))
    (setq p1 (nth 0 dtron) p2 (nth 1 dtron) p3 (nth 2 dtron))
    (setq A12 (angle p1 p2) A13 (angle p1 p3))
    (if (or (equal A12 A13 0.000001) (equal A12 (/ A13 pi) 0.000001) (equal (/ A12 pi) A13 0.000001))
      (setq i (1+ i)); 3 diem thang hang
      (progn
(setq pt2 (mapcar '- p2 p1) pt3 (mapcar '- p3 p1))
        (setq x2 (nth 0 pt2) y2 (nth 1 pt2) x3 (nth 0 pt3) y3 (nth 1 pt3))
        (setq detA (- (* x2 y3) (* y2 x3)) m (* -0.5 (+ (expt x2 2) (expt y2 2))) n (* -0.5 (+ (expt x3 2) (expt y3 2))))
        (setq a (/ (- (* m y3) (* n y2)) detA) b (/ (- (* n x2) (* m x3)) detA))
(setq cen (mapcar '+ p1 (list (- a) (- b) 0.0)))
(setq radius (distance cen p1) sumdis 0.0)
(foreach point lstpt
(setq p point)
(setq dis (- (distance cen p) radius))
(setq sumdis (+ sumdis (expt dis 2)))
);foreach
(setq lcen (append lcen (list cen)) lsum (append lsum (list sumdis)) lrad (append lrad (list radius)) i (1+ i))
);progn
      );if
    );repeat
(setq k (nth 0 (vl-sort-i lsum '<)))
(entmake (list (cons 0 "circle") (cons 10 (nth k lcen)) (cons 40 (nth k lrad))))
  );defun
;------------------------------------------
Tốc độ rất đạt. Nên có thể dùng trong 3D đc với đk phải chia tập hợp n điểm ban đầu thành nhiều tập con chỉ gồm những điểm đồng phẳng.
(P1 P2 . . . Pn) -> ((Pni Pnk ...) (...)) Trong đó (Pn Pnk ... ) là tập hợp con chỉ gồm các điểm có cùng độ cao z
  • 0

Mầm non phường ba - Đây ta mầm cụ
Lãnh tụ non sông - Ngộ không.


#35 NguyenNdait

NguyenNdait

    biết vẽ line

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

Đã gửi 18 December 2010 - 02:36 PM

Chào cả nhà !
Nãy giờ rảnh mình test lại các chương trình của mình cũng như của PTBinh với số lượng điểm khoảng 100 điểm.
Và thật sự thấy đều lâu kinh khủng do có quá nhiều phần tử.
Vậy điều cần thiết là phải có tiêu chí để loại bớt số phần tử trong lúc lấy tổ hợp.
Chúc mọi người ngày cuối tuần vui vẻ.
  • 0

Mầm non phường ba - Đây ta mầm cụ
Lãnh tụ non sông - Ngộ không.


#36 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 19 December 2010 - 11:27 AM

Chào cả nhà !
Nãy giờ rảnh mình test lại các chương trình của mình cũng như của PTBinh với số lượng điểm khoảng 100 điểm.
Và thật sự thấy đều lâu kinh khủng do có quá nhiều phần tử.
Vậy điều cần thiết là phải có tiêu chí để loại bớt số phần tử trong lúc lấy tổ hợp.
Chúc mọi người ngày cuối tuần vui vẻ.

Chào bác NguyenNdait,
Quả thật là việc cơ bản phải giải quyết là thuật toán loại bớt các điểm để giảm thiểu số điểm cần xét. Tuy nhiên do chưa có tiêu chí để loại nên hiện tại mới chỉ là loại các điểm trùng nhau và các điểm thẳng hàng.
Nếu có thể đưa ra thêm các tiếu chí loại điểm nữa thì tốt quá bác ạ.
Mình làm thử bài toán của bạn duyminh86 về xác định mặt phẳng nghiêng.
Hướng giải là
1/- Chọn các nhóm 3 điểm không thẳng hàng.
2/- lập phương trình mặt phẳng qua 3 diểm đó.
3/- Loại bỏ các mặt phẳng có góc tạo với mặt phẳng z=0 một góc nghiêng > 25 độ. (vì chưa rõ cái mặt phẳng vuông góc với đường tâm trụ của bạn duyminh nằm theo kiểu gì nên tạm chọn là hình trụ thẳng đứng, khi cần thiết có thể phải xác định góc giữa mặt phẳng mới tạo với mặt phẳng này)
4/- Lấy bình phương tổng khoảng cách từ các điểm trong tập hợp tới mặt phẳng đó.
5/- Chọn mặt phẳng có giá trị tổng bình phương các khoảng cách là nhỏ nhất
6/- Xác định 3 điểm đó và phương trình mặt phẳng qua 3 điểm này

Kết quả được lisp như sau:

(defun c:nsmp ( / olc lscir ssp p1 p2 lst lst1 lst2 p cir tkc pt pc kc d1 d2 d3 ra lst0)
(command "undo" "be")
(setq oldos (getvar "osmode"))
(setq olc (getvar "cecolor"))
(setvar "osmode" 0)
(setq lscir (list))
(setq ssp (ssget (list (cons 0 "point"))))

(locpoint ssp)

(setq lst0 lst)

(setvar "cecolor" "3")
(foreach e lst
(setq lst1 (vl-remove e lst)
lst (vl-remove e lst)
p (cdr (assoc 10 (entget e)))
x (car p)
y (cadr p)
z (caddr p)
)
(foreach e1 lst1
(setq lst2 (vl-remove e1 lst1)
lst1 (vl-remove e1 lst1)
p1 (cdr (assoc 10 (entget e1)))
x1 (car p1)
y1 (cadr p1)
z1(caddr p1)
d1 (distance p p1)
)
(foreach e2 lst2
(setq p2 (cdr (assoc 10 (entget e2))))
(setq d2 (distance p1 p2)
d3 (distance p2 p)
x2 (car p2)
y2 (cadr p2)
z2 (caddr p2)
)
(if (and (< (+ d1 0.000001) (+ d2 d3)) (< (+ d2 0.000001) (+ d1 d3))
(< (+ d3 0.000001) (+ d1 d2)))
(progn
(setq D (- (+ (* x (- (* y1 z2) (* y2 z1))) (* x1 (- (* y2 z) (* y z2)))
(* x2 (- (* y z1) (* y1 z)))))
A (+ (* y (- z1 z2)) (* y1 (- z2 z)) (* y2 (- z z1)))
B (+ (* z (- x1 x2)) (* z1 (- x2 x)) (* z2 (- x x1)))
C (+ (* x (- y1 y2)) (* x1 (- y2 y)) (* x2 (- y y1)))
)
)
)
(setq tkc 0)
(setq ra (abs (/ C (sqrt (+ (expt A 2) (expt B 2) (expt C 2))))))
(if (>= ra 0.9 )
(progn
(foreach e lst0
(setq pt (cdr (assoc 10 (entget e))))
(setq x0 (car pt)
y0 (cadr pt)
z0 (caddr pt)
)
(setq kc (abs (/ (+ (* A x0) (* B y0) (* C z0) D)
(sqrt (+ (expt A 2) (expt B 2) (expt C 2))))))
(setq tkc (+ tkc (expt kc 2)))
)
(if (= tkc 0)
(progn
(setq mau (list tkc p p1 p2 A B C D))
(ketthuc)
)
(setq lscir (append lscir (list (list tkc p p1 p2 A B C D))))
)
)
)
)
)
)
(setq lscir (vl-sort lscir '(lambda (x y) (< (car x) (car y)) )) )
(setq mau (car lscir))
(ketthuc)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ketthuc ()
(alert (strcat "\n Tong binh phuong khoang cach tu cac diem toi mat phang tim duoc la: "
(rtos (car mau) 2 4)))

(command "point" (cadr mau) )
(command "point" (caddr mau) )
(command "point" (cadddr mau) )
(alert (strcat "\n Mat phang tim duoc di qua ba diem la:" "\n P voi x = " (rtos (car (cadr mau)) 2 4)
"\n y = " (rtos (cadr (cadr mau)) 2 4) "\n z = " (rtos (caddr (cadr mau)) 2 4)
"\n P1 voi x1 = " (rtos (car (caddr mau)) 2 4)
"\n y1 = " (rtos (cadr (caddr mau)) 2 4) "\n z1 = " (rtos (caddr (caddr mau)) 2 4)
"\n P2 voi x2 = " (rtos (car (cadddr mau)) 2 4)
"\n y2 = " (rtos (cadr (cadddr mau)) 2 4) "\n z = " (rtos (caddr (cadddr mau)) 2 4)
"\n Phuong trinh mat phang la: "
"\n" (rtos (nth 4 mau) 2 2) " * x + " (rtos (nth 5 mau) 2 2) " * y + "
(rtos (nth 6 mau) 2 2) " * z + " (rtos (nth 7 mau) 2 2 ) " = 0 "
))

(setvar "osmode" oldos)
(setvar "cecolor" olc)
(command "undo" "e")
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun locpoint (ssp / lstpt i n e p)
(setq lstpt (list)
lst (list)
)
(if ssp
(progn
(setq i 0
n (sslength ssp)
)
(while (< i n)
(setq e (ssname ssp i))
(setq p (cdr (assoc 10 (entget e))))
(if (not (member p lstpt))
(progn
(setq lstpt (append lstpt (list p)))
(setq lst (append lst (list e)))
)
;;;;;(command "erase" e "")
(entdel e)
)
(setq i (1+ i))
)
)
)
lst
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;


Kết quả chạy thử cho thấy:
1/- Lisp này chạy nhanh hơn lisp nội suy tâm vòng tròn đi qua tập hợp điểm đồng phẳng do không cần phải dựng vòng tròn qua ba điểm.
2/- Lisp chỉ cho người dùng biết 3 điểm đã tạo ra mặt phẳng và phương trình của mặt phẳng cũng như tổng bình phương các khoảng cách từ các điểm trong tập hợp điểm được chọn tới mặt phẳng đó để người dùng tùy nghi sử dụng.
3/- Đây chưa phải là mặt phẳng tối ưu, có tổng bình phương khoảng cách từ các điểm tới nó là nhỏ nhất, song nó là tối ưu trong số các mặt phẳng đi qua 3 điểm bất kỳ không thẳng hàng của tập hợp điểm.
4/- Có thể loại bớt các mặt phẳng này bằng cách hạn chế góc nghiêng của nó so với mặt phẳng chuẩn để lisp chạy nhanh hơn.

Rất mong các bác dùng thử và cho ý kiến để hoàn thiện nó.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#37 duyminh86

duyminh86

    biết pan

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

Đã gửi 24 December 2010 - 09:07 AM

Hề hề hề,
Thực ra thì với cách tổ hợp 3 điểm này thì với cả 3D nó cũng như rứa. Chỉ có điều các mặt phẳng tạo bởi 3 điểm này không phải lúc nào cũng thỏa mãn là nghiêng với mặt phẳng vuông góc đường tâm trụ một góc nằm trong giới hạn như bạn yêu cầu mà thôi. Như vậy có nhẽ phải tính đến việc xét góc của mặt phẳng tạo bởi 3 điểm với mặt phảng cho trước bạn ạ.
Chắc chắn các bác trên diễn đàn sẽ có võ trị được nó, bạn yên tâm chờ đợi nhé....
Hề hề hề.



Rất cám ơn các bác phamthanhbinh, Tue_NV, NguyenNdait, DuongTrungHuy và tất cả các thành viên tham gia topic đã giúp đỡ.

Em quên mất ko nói với các bác là vẫn đề mà em nhờ các bác giải quyết thực ra nó chỉ có giới hạn số lượng điểm thôi các bác ạ, cùng lắm là 20 điểm thôi.

Thế nên vấn đề về tốc độ có lẽ ko cần tới, nhưng nó đòi hỏi phải làm trên 3D.

Chương trình của các bác rất tốt trên 2D nhưng khi em thử trên 3D thì ko cho ra kết quả các bác ạ. Nó sai như sau:
Hình đã gửi
Ở phía bên phải em lấy các điểm trên cùng mặt phẳng thì OK, nhưng khi lấy các điểm trong không gian nghiêng như bên phải thì cho ra hình tròn sai.

Các bác giúp em nhé.

Cám ơn các bác rất nhiều! :undecided:
  • 0

#38 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 24 December 2010 - 11:27 AM

Rất cám ơn các bác phamthanhbinh, Tue_NV, NguyenNdait, DuongTrungHuy và tất cả các thành viên tham gia topic đã giúp đỡ.

Em quên mất ko nói với các bác là vẫn đề mà em nhờ các bác giải quyết thực ra nó chỉ có giới hạn số lượng điểm thôi các bác ạ, cùng lắm là 20 điểm thôi.

Thế nên vấn đề về tốc độ có lẽ ko cần tới, nhưng nó đòi hỏi phải làm trên 3D.

Chương trình của các bác rất tốt trên 2D nhưng khi em thử trên 3D thì ko cho ra kết quả các bác ạ. Nó sai như sau:
Hình đã gửi
Ở phía bên phải em lấy các điểm trên cùng mặt phẳng thì OK, nhưng khi lấy các điểm trong không gian nghiêng như bên phải thì cho ra hình tròn sai.

Các bác giúp em nhé.

Cám ơn các bác rất nhiều! :undecided:

Hề hề hề,
Cái nhà ông chủ thớt này đoảng quá. Kiểu này thì ế hàng to đấy.
Cái lisp dành cho các điểm nằm trong không gian , tức là xác định mặt phẳng nghiêng vói mặt phẳng nằm ngang một góc nhỏ hơn 25 độ (Ở đây coi như mình chọn hình trụ có trục vuông góc với mặt phẳng ngang Z=0 ) có tổng bình phương khoảng cách tới các điểm trong tập hợp chọn là nhỏ nhất, đã được mình post lên từ mấy ngày trước rồi mà ông chủ thớt không thèm ngó ngàng chi tới. Thiệt tình .......
Bạn hãy test cái lisp đó xem đã ưng ý chưa và còn cần sử chữa gì thì nói nhé. (bài post số 123968 , trước bài post cuối cùng của bạn)
Gì chứ cỡ 20 điểm thì lisp này chạy ngon , chỉ khoảng một phút là xong tất.....
Hề hề hề....
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#39 thiep

thiep

    biết dimbaseline

  • Members
  • PipPipPipPipPip
  • 369 Bài viết
Điểm đánh giá: 260 (khá)

Đã gửi 27 December 2010 - 03:50 PM

Chào bác NguyenNdait,
Quả thật là việc cơ bản phải giải quyết là thuật toán loại bớt các điểm để giảm thiểu số điểm cần xét. Tuy nhiên do chưa có tiêu chí để loại nên hiện tại mới chỉ là loại các điểm trùng nhau và các điểm thẳng hàng.
Nếu có thể đưa ra thêm các tiếu chí loại điểm nữa thì tốt quá bác ạ.
Mình làm thử bài toán của bạn duyminh86 về xác định mặt phẳng nghiêng.
Hướng giải là
1/- Chọn các nhóm 3 điểm không thẳng hàng.
2/- lập phương trình mặt phẳng qua 3 diểm đó.
3/- Loại bỏ các mặt phẳng có góc tạo với mặt phẳng z=0 một góc nghiêng > 25 độ. (vì chưa rõ cái mặt phẳng vuông góc với đường tâm trụ của bạn duyminh nằm theo kiểu gì nên tạm chọn là hình trụ thẳng đứng, khi cần thiết có thể phải xác định góc giữa mặt phẳng mới tạo với mặt phẳng này)
4/- Lấy bình phương tổng khoảng cách từ các điểm trong tập hợp tới mặt phẳng đó.
5/- Chọn mặt phẳng có giá trị tổng bình phương các khoảng cách là nhỏ nhất
6/- Xác định 3 điểm đó và phương trình mặt phẳng qua 3 điểm này

Kết quả được lisp như sau:


(defun c:nsmp ( / olc lscir ssp p1 p2 lst lst1 lst2 p cir tkc pt pc kc d1 d2 d3 ra lst0)
(command "undo" "be")
(setq oldos (getvar "osmode"))
(setq olc (getvar "cecolor"))
(setvar "osmode" 0)
(setq lscir (list))
(setq ssp (ssget (list (cons 0 "point"))))

(locpoint ssp)

(setq lst0 lst)

(setvar "cecolor" "3")
(foreach e lst
(setq lst1 (vl-remove e lst)
lst (vl-remove e lst)
p (cdr (assoc 10 (entget e)))
x (car p)
y (cadr p)
z (caddr p)
)
(foreach e1 lst1
(setq lst2 (vl-remove e1 lst1)
lst1 (vl-remove e1 lst1)
p1 (cdr (assoc 10 (entget e1)))
x1 (car p1)
y1 (cadr p1)
z1(caddr p1)
d1 (distance p p1)
)
(foreach e2 lst2
(setq p2 (cdr (assoc 10 (entget e2))))
(setq d2 (distance p1 p2)
d3 (distance p2 p)
x2 (car p2)
y2 (cadr p2)
z2 (caddr p2)
)
(if (and (< (+ d1 0.000001) (+ d2 d3)) (< (+ d2 0.000001) (+ d1 d3))
(< (+ d3 0.000001) (+ d1 d2)))
(progn
[color="#FF0000"](setq D (- (+ (* x (- (* y1 z2) (* y2 z1))) (* x1 (- (* y2 z) (* y z2)))
(* x2 (- (* y z1) (* y1 z)))))
A (+ (* y (- z1 z2)) (* y1 (- z2 z)) (* y2 (- z z1)))
B (+ (* z (- x1 x2)) (* z1 (- x2 x)) (* z2 (- x x1)))
C (+ (* x (- y1 y2)) (* x1 (- y2 y)) (* x2 (- y y1)))
)
)
)
(setq tkc 0)
(setq ra (abs (/ C (sqrt (+ (expt A 2) (expt B 2) (expt C 2))))))[/color]
(if (>= ra 0.9 )
(progn
(foreach e lst0
(setq pt (cdr (assoc 10 (entget e))))
(setq x0 (car pt)
y0 (cadr pt)
z0 (caddr pt)
)
(setq kc (abs (/ (+ (* A x0) (* B y0) (* C z0) D)
(sqrt (+ (expt A 2) (expt B 2) (expt C 2))))))
(setq tkc (+ tkc (expt kc 2)))
)
(if (= tkc 0)
(progn
(setq mau (list tkc p p1 p2 A B C D))
(ketthuc)
)
(setq lscir (append lscir (list (list tkc p p1 p2 A B C D))))
)
)
)
)
)
)
(setq lscir (vl-sort lscir '(lambda (x y) (< (car x) (car y)) )) )
(setq mau (car lscir))
(ketthuc)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ketthuc ()
(alert (strcat "\n Tong binh phuong khoang cach tu cac diem toi mat phang tim duoc la: "
(rtos (car mau) 2 4)))

(command "point" (cadr mau) )
(command "point" (caddr mau) )
(command "point" (cadddr mau) )
(alert (strcat "\n Mat phang tim duoc di qua ba diem la:" "\n P voi x = " (rtos (car (cadr mau)) 2 4)
"\n y = " (rtos (cadr (cadr mau)) 2 4) "\n z = " (rtos (caddr (cadr mau)) 2 4)
"\n P1 voi x1 = " (rtos (car (caddr mau)) 2 4)
"\n y1 = " (rtos (cadr (caddr mau)) 2 4) "\n z1 = " (rtos (caddr (caddr mau)) 2 4)
"\n P2 voi x2 = " (rtos (car (cadddr mau)) 2 4)
"\n y2 = " (rtos (cadr (cadddr mau)) 2 4) "\n z = " (rtos (caddr (cadddr mau)) 2 4)
"\n Phuong trinh mat phang la: "
"\n" (rtos (nth 4 mau) 2 2) " * x + " (rtos (nth 5 mau) 2 2) " * y + "
(rtos (nth 6 mau) 2 2) " * z + " (rtos (nth 7 mau) 2 2 ) " = 0 "
))

(setvar "osmode" oldos)
(setvar "cecolor" olc)
(command "undo" "e")
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun locpoint (ssp / lstpt i n e p)
(setq lstpt (list)
lst (list)
)
(if ssp
(progn
(setq i 0
n (sslength ssp)
)
(while (< i n)
(setq e (ssname ssp i))
(setq p (cdr (assoc 10 (entget e))))
(if (not (member p lstpt))
(progn
(setq lstpt (append lstpt (list p)))
(setq lst (append lst (list e)))
)
;;;;;(command "erase" e "")
(entdel e)
)
(setq i (1+ i))
)
)
)
lst
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;


Kết quả chạy thử cho thấy:
1/- Lisp này chạy nhanh hơn lisp nội suy tâm vòng tròn đi qua tập hợp điểm đồng phẳng do không cần phải dựng vòng tròn qua ba điểm.
2/- Lisp chỉ cho người dùng biết 3 điểm đã tạo ra mặt phẳng và phương trình của mặt phẳng cũng như tổng bình phương các khoảng cách từ các điểm trong tập hợp điểm được chọn tới mặt phẳng đó để người dùng tùy nghi sử dụng.
3/- Đây chưa phải là mặt phẳng tối ưu, có tổng bình phương khoảng cách từ các điểm tới nó là nhỏ nhất, song nó là tối ưu trong số các mặt phẳng đi qua 3 điểm bất kỳ không thẳng hàng của tập hợp điểm.
4/- Có thể loại bớt các mặt phẳng này bằng cách hạn chế góc nghiêng của nó so với mặt phẳng chuẩn để lisp chạy nhanh hơn.
Rất mong các bác dùng thử và cho ý kiến để hoàn thiện nó.

Chào bác Bình, sau khi đọc lisp của bác, Thiep có 1 số thắc mắc và nhận xét sau:
- Lisp của bác có mấy công thức xác định A, B, C, D, Thiep hiểu là các thông số của pT mặt phẳng đi qua 3 điểm p, p1, p2: Ax+By+Cz+D=0, không biết có đúng không nữa.
- Tuy nhiên, từ đây, bác xác định: ra, có phải là bán kính của đường tròn đi qua 3 điểm trên không? Nếu đúng thì sao nó không phụ thuộc vào thông số D? Và tại sao bác đặt điều kiện: ra>=0.9?
- Bác xác định kc, theo Thiep thì đây chỉ là khoảng cách từ điểm P0 đến mặt phẳng Ax+By+Cz+D=0, chứ chưa phải là khoảng cách ngắn nhất từ P0 đến đường tròn đi qua 3 điểm p1, p2, p3. Và kc luôn luôn là số dương nên không cần thêm hàm abs.
- Bác dùng hàm này thay cho hàm locpoint của bác:
(ACET-LIST-REMOVE-DUPLICATEs lst nil): Hàm này sẽ loại bỏ hết các phần tử trùng lập, hoặc gần trùng trong 1 list, trong đó: lst là 1 list, các phần tử có thể là tọa độ của điểm, có thể là string ..., nil là sai số so sánh.
Thân chào bác.
  • 0

#40 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 27 December 2010 - 05:02 PM

Chào bác Bình, sau khi đọc lisp của bác, Thiep có 1 số thắc mắc và nhận xét sau:
- Lisp của bác có mấy công thức xác định A, B, C, D, Thiep hiểu là các thông số của pT mặt phẳng đi qua 3 điểm p, p1, p2: Ax+By+Cz+D=0, không biết có đúng không nữa.
- Tuy nhiên, từ đây, bác xác định: ra, có phải là bán kính của đường tròn đi qua 3 điểm trên không? Nếu đúng thì sao nó không phụ thuộc vào thông số D? Và tại sao bác đặt điều kiện: ra>=0.9?
- Bác xác định kc, theo Thiep thì đây chỉ là khoảng cách từ điểm P0 đến mặt phẳng Ax+By+Cz+D=0, chứ chưa phải là khoảng cách ngắn nhất từ P0 đến đường tròn đi qua 3 điểm p1, p2, p3. Và kc luôn luôn là số dương nên không cần thêm hàm abs.
- Bác dùng hàm này thay cho hàm locpoint của bác:
(ACET-LIST-REMOVE-DUPLICATEs lst nil): Hàm này sẽ loại bỏ hết các phần tử trùng lập, hoặc gần trùng trong 1 list, trong đó: lst là 1 list, các phần tử có thể là tọa độ của điểm, có thể là string ..., nil là sai số so sánh.
Thân chào bác.

Hề hề hề,
Bác thiep chỉ được cái nói đúng. Vì bạn duyminh86 nói là dựng mặt phẳng sao cho tổng bình phương khoảng các từ các điểm tới mặt phẳng đó là nhỏ nhất chớ không phải là tổng bình phương khoảng cách tới vòng tròn đi qua ba điểm bác ạ (Đây là bài toán khác với bài trước)
Cái điều kiện ra>=0.9 vì ra là cos của góc tạo bởi mặt phẳng qua 3 điểm với mặt phẳng chuẩn (mà ở đây mình lấy là mắt z=0) nên khi ra>=0.9 góc nghiêng này sẽ nhỏ hơn 25 độ bác ạ. Mục đích là để loại bớt các mặt phẳng quá nghiêng như bạn DUYMINH86 nói mà thôi bác à.
Thực ra kc đúng là số dương nhưng tại vì trong công thức giải tích có cái căn nên mình sợ nó lấy cả giá trị âm thì bỏ bu nên chơi vầy cho chắc cú thối bác ạ.
Cám ơn bác về cái hàm (acet-list-remove-duplicates lst nil) , vì cái khoản về các hàm acet này mình chưa mót được nhiều bác ạ.
Chúc bác khỏe và vui nhân dịp năm mới...
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.