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

[Yêu cầu] Lisp phân nhỏ tập hợp chọn bằng cách chia ô

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

Bạn test xem đúng yêu cầu không nhé.

(defun C:HA1()
(command "zoom" "e")
(princ "\nChuong trinh dang chay. Xin vui long doi...\n")
(setq hcnlst (mapcar '(lambda (x) (list (car x) (cadr x))) (select-c (getvar "extmin") (getvar "extmax") 500 '((0 . "LINE"))))))
(defun select-c (p1 p2 n filter)
(if (setq ss (ssget "c" p1 p2 filter))
 (if (< (sslength ss) (abs (setq n (* -1 n))))
  (list (list p1 p2))
  (if (< n 0)
(append (select-c p1 (list (* 0.5 (+ (car p2) (car p1))) (cadr p2)) n filter) (select-c p2 (list (* 0.5 (+ (car p2) (car p1))) (cadr p1)) n filter))
(append (select-c p1 (list (car p2) (* 0.5 (+ (cadr p2) (cadr p1)))) n filter) (select-c p2 (list (car p1) (* 0.5 (+ (cadr p2) (cadr p1)))) n filter))))))
(defun C:HA2()
(setq p (getpoint "\nPick point: "))
(setq lst1 '())
(foreach hcn hcnlst
 (if (not (HA:InOut hcn p))
  (setq lst1 (cons hcn lst1))))
lst1)
(defun HA:InOut (hcn p / lst tt z n)
(setq lst (list
    			(list (car (cadr hcn)) (cadr (cadr hcn)))
    			(car hcn)
    			(list (car (car hcn)) (cadr (cadr hcn)))
    			(cadr hcn)))
(setq z 0)
(repeat (1- (length lst))
 (if (< (sin (- (angle p (nth z lst)) (angle p (nth (1+ z) lst)))) -1e-14) (setq n T))
 (setq z (1+ z)))
n)

 

Hôm nay mình bắt đầu dùng đến hai cái hàm nhờ bạn viết đã lâu, kg biết bạn còn nhớ kg nữa.

Mình nhắc lại một tý. Căn cứ vào hàm phân nhỏ tập hợp chọn bằng cách chia ô của bác Thai, mình có nhờ và bạn đã viết giúp 2 hàm ở #53 và #52.

- Hàm thứ nhất căn cứ vào các hình chữ nhất có trên bv sau khi chia ô, người sd cung cấp 1 điểm, nó trả về ename HCN bao quanh nó. Hàm này mình đã kiểm tra, kq khá chính xác.

- Hàm thứ hai mình yêu cầu là kg vẽ ra HCN mà chỉ căn cứ vào list lưu HCN thôi, người sd cung cấp 1 điểm, yêu cầu hàm trả về hai đỉnh HCN. Hàm này chạy chưa chính xác lắm. Có lúc nó trả về nil mặc dù điểm chọn nắm bên trong các đt. Nếu bạn có thới gian hoặc lúc nàio rãnh rỗi xin xem lại giúp cho nó chạy tốt. Sau đó chỉnh lại giúp mình một tý, thay vì trả vể hai đỉnh HCN thì chỉ cần trả về vỉ trí của nó trong cái list kia thôi. Cám ơn bạn.

Thật ra mình cũng có viết một hàm tương tự như vậy, nhưng hàm này thường xuyên đc sd nên mình muốn chọn một cái thật nhanh. code như sau :

;Ham kiem tra vi tri ddiem va HCN
(defun diemvaHCN( p1 p2 p / x y x1 y1 x2 y2 k)
 (setq x (car p) y (cadr p) x1 (car p1) y1 (cadr p1) x2 (car p2) y2 (cadr p2))
 (if (> x1 x2) (setq k x1 x1 x2 x2 k))
 (if (> y1 y2) (setq k y1 y1 y2 y2 k))
 (cond
((if (or (< x x1) (< y y1) (> x x2) (> y y2)) 1)) ; khi p nam ngoai HCN (p1 p2)
((if (and (> x x1) (< x x2) (> y y1) (< y y2)) -1)) ; khi p nam trong HCN (p1 p2)
(T 0) ; khi p nam trung HCN (p1 p2)
 )
)
;Tim vi tri diem thuoc ô HCN nao
(defun diemvaHCNchiaO( p / i ds dstam kt)
 (if (null ltd_dsHCNchiao) (setq ltd_dsHCNchiao (sschiao)))
 (setq dstam ltd_dsHCNchiao)
 (setq i 0 ds (car dstam) kt 1)
 (while (and ds (> (setq kt (diemvahcn (car ds) (cadr ds) p)) 0))
(setq i (1+ i))
(setq dstam (cdr dstam))
(setq ds (car dstam))
 )
 (if (<= kt 0) i nil)
)
;ham tao list hcn theo o
(defun SSCHIAO( / ss box p1 p2 lis)
 (if (setq ss (ssget "x" '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (progn
;	(setq box (ACET-GEOM-SS-EXTENTS-FAST ss) p1 (car box) p2 (cadr box))
(setq p1 (getvar "extmin") p2 (getvar "extmax"))
(command "_.zoom" p1 p2)
(setq lis (select-c p1 p2 200 '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
lis) nil)
)

Nếu bạn nào có giải thuật thật nhanh thì xin giúp 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

Dạo này thấy cadviet có lẽ hơi lắng lại thì phải. Mình thì có nhiều ý tưởng, tuy nhiên nó kỳ quái kg giống ai nên cũng ít bạn quan tâm, hơn nữa các bạn cũng lắm việc nên những gì dài hơi khó nhắn thường cũng bị quên lãng. Nhiều lúc nghĩ để tự mình cố suy nghĩ để làm cho rồi nhưng mà đúng là "một cây làm chẳng lên non", hơn nữa suy nghĩ đã theo lối mòn thường cũng dễ bí.

Vừa qua, được sự giúp đỡ của bác Thai, bác ĐVH(kg phải là Đàm Vĩnh Hưng đâu nhé), bác Bình và các bạn, mình đã ứng dụng PP chia ô và đạt những kq hết sức ngoạn mục. Nó đã cải tiến rất rõ và mở ra một tư duy mới trong lập trình phân mảnh (cái này do mình đặt ra chứ dân chuyên nghiệp kg biết gôi là gì). Có lẽ sắp tới mình phải viết lại một số code cũ để vận dụng PP này. Tuy nhiên, nó mới chỉ là thành công bước đầu, để có thể chuẩn hóa và đa dạng hóa nó cũng cần thêm một số điều cần làm.

- Một là : PP của bác Thai đã cơ bản quản lý đc mô hình mật độ đối tượng. Tuy nhiên, do các hình chữ nhật đc sinh ra theo một quy luật "tương đối tự do" (do mình chưa thấy đc trật tự của nó) nên chúng ta chưa thể truy xuất nhanh đc chúng. Ví dụ, sau khi đã quản lý các HCN vào list, khi cung cấp một điểm, ta chưa thể chỉ ra thật nhanh điểm đó thuộc HCN nào; và khi cần thiết, ta chưa tìm nhanh đc các HCN liền kề với HCN trên.

Nói đến đây, các bạn có thể đoán biết mình cần một thuật toán nào đó, hay một tư duy nào nó có thể thấy đc trật tự (qui luật) của các HCN đc sinh ra để quản lý nó sao cho có thể tuy xuất thật nhanh vị trí của nó trong list và các HCN liền kế nó khi cần.

 

- Hai, chúng ta phải ép các HCN đc sinh theo qui luật. VD, khi có hai điểm bao tập hợp đt ban đầu, ta làm tròn nó đến số chẵn (VD (0 0) (1000,500), sao đó sẽ sinh ra các HCN con cũng có tọa độ chẵn, ... để tính toán vị trí của nó bằng công thức chứ kg cần tìm nó bằng PP lặp và kiểm tra tọa độ.

Thật ra mình chưa đưa ra đc cái mô hình của nó nên chưa diễn giải đc một cách trơn tru dễ hiểu, tại vì nó rất trừu tượng, nếu chúng ta cụ thể hóa nó ta sẽ có một giải thuật tối ưu để thực hiện nó.

 

Tóm lại, ý mình như vậy :

- Một là đưa ra các HCN để phân nhỏ tập hợp chọn theo một qui luật nào đó (VD như bác Thai đã làm).

- Hai là cách quản lý và truy xuất nó thật nhanh (khi ta cung cậo một điểm-> truy xuất ngay HCN chứa nó (tức vị trí của HCN trong list HCN) ; khi cung cấp một HCN-> truy xuất ngay các HCN liền kề (bằng vị trí của nó trong list HCN)).

 

Mình đưa lên đây hy vọng tìm đc những ý tưởng hay, đồng cảm, chia sẻ của các bạn. Xin 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

×