Đến nội dung


Hình ảnh
- - - - -

Biến pl phức tạp thành đơn giản mà diện tích không đổi


  • Please log in to reply
50 replies to this topic

#1 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 12 April 2011 - 02:09 AM

Chào các bạn, tôi có một việc cần sự giúp đỡ của các bạn, các bạn có thể viết hay gợi ý cho tôi.
Tôi đã tìm thấy trên diễn đàn một số lisp đổi polyline dạng phức tạp gốm line, arc, spline ... thành dạng polyline chỉ có line, nhưng những lisp này chưa đáp ứng hết nhu cầu mà tôi cần.
Tôi cần một lisp biến đổi một polyline kín phức tạp thành pl gồm toàn line gần với pl gốc nhất, nhưng khi biến đổi chỉ biến đổi những dạng đường cong (arc, spline)về line mà thôi, còn những đoạn đã là line thì kg cần cắt nhỏ ra (trên diễn đàn có lisp cắt nhỏ như vậy)
Mặc khác, khi biến đổi những đoạn cong về thành đoạn thẳng, không bắt buộc đỉnh đoạn thẳng phải nằm trên đường cong, chúng có thể nằm về hai phía đường cong để bảo đảm diện tích gần như không đổi và gần với đường cong gốc nhất.
Việc giữ kg đổi diện tích buộc pl mới sẽ lệch khỏi pl gốc, do đó dẫn đến có thể đòi hỏi độ dài mỗi đoạn thẳng tạo ra hay khoảng cách từ đỉnh đoạn thẳng đến pl gốc sao cho có thể chấp nhận từ người dùng (có nghĩa nó cần nhập vào).
Tỷ lệ bản vẽ tôi đang dùng là 1:1, 1 đơn vị = 1 mét, diện tích cần chính xác đến 0.1m2
Xin chân thành cám ơn
  • 0

#2 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 12 April 2011 - 07:40 AM

Chào các bạn, tôi có một việc cần sự giúp đỡ của các bạn, các bạn có thể viết hay gợi ý cho tôi.
Tôi đã tìm thấy trên diễn đàn một số lisp đổi polyline dạng phức tạp gốm line, arc, spline ... thành dạng polyline chỉ có line, nhưng những lisp này chưa đáp ứng hết nhu cầu mà tôi cần.
Tôi cần một lisp biến đổi một polyline kín phức tạp thành pl gồm toàn line gần với pl gốc nhất, nhưng khi biến đổi chỉ biến đổi những dạng đường cong (arc, spline)về line mà thôi, còn những đoạn đã là line thì kg cần cắt nhỏ ra (trên diễn đàn có lisp cắt nhỏ như vậy)
Mặc khác, khi biến đổi những đoạn cong về thành đoạn thẳng, không bắt buộc đỉnh đoạn thẳng phải nằm trên đường cong, chúng có thể nằm về hai phía đường cong để bảo đảm diện tích gần như không đổi và gần với đường cong gốc nhất.
Việc giữ kg đổi diện tích buộc pl mới sẽ lệch khỏi pl gốc, do đó dẫn đến có thể đòi hỏi độ dài mỗi đoạn thẳng tạo ra hay khoảng cách từ đỉnh đoạn thẳng đến pl gốc sao cho có thể chấp nhận từ người dùng (có nghĩa nó cần nhập vào).
Tỷ lệ bản vẽ tôi đang dùng là 1:1, 1 đơn vị = 1 mét, diện tích cần chính xác đến 0.1m2
Xin chân thành cám ơn

Chào bác TrungNgaMy
em hiểu ý của bác, nhưng có ý này của bác chưa hiểu lắm :
độ dài mỗi đoạn thẳng tạo ra hay khoảng cách từ đỉnh đoạn thẳng đến pl gốc sao cho có thể chấp nhận từ người dùng (có nghĩa nó cần nhập vào)
Bác có thể nói rõ hơn, hoặc là bác có thể gửi file minh họa cho ý này của bác được không?
  • 0

#3 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 12 April 2011 - 10:43 AM

Chào bác TrungNgaMy
độ dài mỗi đoạn thẳng tạo ra hay khoảng cách từ đỉnh đoạn thẳng đến pl gốc sao cho có thể chấp nhận từ người dùng (có nghĩa nó cần nhập vào)

Không biết ý của TrungNgaMy có phải như vậy không?
-Khoảng cách từ đường line đã mô phỏng đó đến đường arc hoặc spline là 1 số mà người sử dụng cho phép ví dụ là 0.1 hoặc 0.2, khoảng cách từ đường line đã mô phỏng ở đây có thế tạm hiểu là khoảng cách lớn nhất từ các điểm thuộc line đến đường Spline.
-Chiều dài mỗi đoạn line mô phỏng là người dùng nhập vào ví dụ 5.2 hoặc 2.5 tùy ý.
Mình dự đoán vậy k biết có đúng ý không? Bạn thử giúp TrungNgaMy tí.
  • 0

#4 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 12 April 2011 - 12:15 PM

Không biết ý của TrungNgaMy có phải như vậy không?
-Khoảng cách từ đường line đã mô phỏng đó đến đường arc hoặc spline là 1 số mà người sử dụng cho phép ví dụ là 0.1 hoặc 0.2, khoảng cách từ đường line đã mô phỏng ở đây có thế tạm hiểu là khoảng cách lớn nhất từ các điểm thuộc line đến đường Spline.
-Chiều dài mỗi đoạn line mô phỏng là người dùng nhập vào ví dụ 5.2 hoặc 2.5 tùy ý.
Mình dự đoán vậy k biết có đúng ý không? Bạn thử giúp TrungNgaMy tí.

Cám ơn các bạn. Bạn đoán vậy đúng rồi. Tuy nhiên, mình đính chính một tý: các ĐỈNH của các đoạn thẳng tạo thành nên uốn lượn theo đường cong càng giống càng tốt chứ kg cần nằm về hai phía của nó. Mình gởi hình cho các bạn
Hình đã gửi
  • 0

#5 anonmyous

anonmyous

    biết vẽ arc

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

Đã gửi 12 April 2011 - 03:38 PM

Cám ơn các bạn. Bạn đoán vậy đúng rồi. Tuy nhiên, mình đính chính một tý: các ĐỈNH của các đoạn thẳng tạo thành nên uốn lượn theo đường cong càng giống càng tốt chứ kg cần nằm về hai phía của nó. Mình gởi hình cho các bạn
Hình đã gửi


Mục đích của bác muốn biến đổi vậy để làm gì, dựng WipeOut cho nhanh chăng, còn độ chính xác thì cái này ở phần đầu vào ta có thể cho nó một tham số khống chế chiều dài đoạn chia, nhập & chạy lại LISP cho đến khi kết quả thỏa mãn
  • 0

#6 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 13 April 2011 - 01:12 AM

Mục đích của bác muốn biến đổi vậy để làm gì, dựng WipeOut cho nhanh chăng, còn độ chính xác thì cái này ở phần đầu vào ta có thể cho nó một tham số khống chế chiều dài đoạn chia, nhập & chạy lại LISP cho đến khi kết quả thỏa mãn

Cám ơn bạn. Mục đích của mình kg như bạn nghĩ, Mình làm về địa chính nên muốn cụ thể hóa các đoạn cong thành điểm có thể để quản lý hay cắm công trình mà quan trọng nhất là diện tích thay đổi kg đáng kể (tùy thuộc vào độ cong, với những đg cong có bán kính lớn thì độ lệch càng nhỏ và ngược lại) nhưng còn phụ thuộc vào khả năng của chương trình. Ý bạn nói câu này "còn độ chính xác thì cái này ở phần đầu vào ta có thể cho nó một tham số khống chế chiều dài đoạn chia, nhập & chạy lại LISP cho đến khi kết quả thỏa mãn". Bạn đang nói đến một lisp nào đó chăng. Lisp mình trích đc trên diễn đàn (kg rõ tác giả) kg thực hiện như nhu cầu của mình. Lisp đó chia nhỏ kể cả những đoạn thẳng

Theo mình vđ này kg đơn giản nên mới cầu cứu đến các bạn.
  • 0

#7 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 13 April 2011 - 08:23 AM

Chỉ nguyên vấn đề diện tích thay đổi không đáng kể + độ dài line giới hạn nhập vào từ user đã làm cho bài toán có rất rất nhiều nghiệm bác ơi, và chạy thì không biết đến bao giờ ^^
  • 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


#8 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 13 April 2011 - 09:34 AM

Chỉ nguyên vấn đề diện tích thay đổi không đáng kể + độ dài line giới hạn nhập vào từ user đã làm cho bài toán có rất rất nhiều nghiệm bác ơi, và chạy thì không biết đến bao giờ ^^

'ketxu' thử theo ý tưởng này xem có được k?
-Các đoạn thẳng thì lấy tọa độ đỉnh
-Các đoạn cong thì chia đều chẳng hạn thành 10 đoạn nhỏ rồi lấy tọa độ các điểm đó (hàm vlax-curve-getPointAtDist... chắc bạn biết)
-Tính lại sai số diện tích tương đối của đường thật và đường đã xấp xỉ nếu sai số > cho phép thì chia nhỏ hơn.
Thuật toán này chỉ nội tiếp trong đường cong chứ cả "ngoại tiếp" như Bạn TRUNGNGAMY thì hóc búa thật... :)
Nếu được, Bạn thử xem nhé!
  • 0

#9 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 13 April 2011 - 09:41 AM

Chỉ trên đường cong thì công việc đơn giản rồi ^^ Vấn đề là bác Trung còn muốn cả nội ngoại kết hợp bất kỳ sao cho delta (kcách giữa đỉnh line với spline), total length (max khoảng cách 2 đỉnh Line sau khi chia) và delta S là nhỏ nhất. Điều này sẽ làm chương trình vừa phức tạp vừa khó xơi , và e thì chắc chắn là bỏ của chạy lấy thân r ^^
  • 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


#10 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 13 April 2011 - 11:56 AM

Chỉ trên đường cong thì công việc đơn giản rồi ^^ Vấn đề là bác Trung còn muốn cả nội ngoại kết hợp bất kỳ sao cho delta (kcách giữa đỉnh line với spline), total length (max khoảng cách 2 đỉnh Line sau khi chia) và delta S là nhỏ nhất. Điều này sẽ làm chương trình vừa phức tạp vừa khó xơi , và e thì chắc chắn là bỏ của chạy lấy thân r ^^

Hình đã gửi
Cám ơn các bạn. Cũng có những vđ khó mình tham khảo ý tưởng hay các bạn, việc đc hay kg cũng còn tùy hên xui nhưng đều rất đáng quý tấm lòng của các bạn.
Các bạn xem hình. Nếu các đỉnh line nội tiếp đường cong thì diện tích sẽ lớn hoặc nhỏ hơn diện tích cũ. Nếu ta tính đc khoảng dời theo phía ngược lại thì diện tích trong ngoài sẽ bù nhau (tất nhiên phải chú ý hai điểm đầu cuối). Khoảng dời này là bao nhiêu thì mình đang bí.
  • 0

#11 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 13 April 2011 - 02:55 PM

Bạn thử cái này xem sao!
(defun c:Xapxi()
(setvar "osmode" 0) (setvar "cmdecho" 0)
(setq e1 (car (entsel "\nCho duong: "))
nd (getint "\nCho so khoang chia: ")
ds1 (acet-geom-vertex-list e1)
)
(command "Area" "o" e1)
(setq Chdai (getvar "Perimeter") S0 (getvar "Area")
ni 0 ld (/ Chdai nd) l0 0 dsdiem '()
)
(While (< l0 (+ 0.001 Chdai))
(setq dsdiem (append dsdiem (list (vlax-curve-getPointAtDist e1 l0)))
l0 (+ l0 ld)
)
)
(command "Spline")
(Foreach pt dsdiem (command pt)) (command "" "" "")
(setq e2 (entlast) ds2 (acet-geom-vertex-list e2))
(entdel e2)
(command "pline")(Foreach pt ds2 (command pt))(command "")
(setq e2 (entlast) s2 (vlax-curve-getarea e2))
(print (list s0 s2 "Sai so la: % " (/ (- s0 s2) s0 0.01)))
(princ)
)

Ghi chú: Với "ARC" Bạn chuyển qua Poly rồi hãy chạy c:Xapxi với Spline thì thôi!
  • 1

#12 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 13 April 2011 - 03:43 PM

Nếu như thế này thì vẫn là phép dò đúng không ạ ? chứ chưa giới hạn dS từ đầu.
Code chạy đẹp lắm, tks bác
  • 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


#13 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 13 April 2011 - 03:50 PM

... tks bác

Thế này chứ 'ketxu'
-Nếu muốn thì ta đưa thêm vòng lặp. ban đầu cho số điểm là 5 nếu dS>[dS] cho phép thì tăng len là 5*2 nếu được thì thôi còn không thì tăng lên 5*2*2...
Chúc vui vẻ! :)
  • 0

#14 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 13 April 2011 - 04:01 PM

Thì vẫn là phép thử dần mà ^^ Khà khà. Vì là phép thử dần của bác đã tạo ra đối tượng mới rồi mới kiểm tra S, nên trong trường hợp cần 5*2^1000 lần chẳng hạn, thì ...khà khà ^^ Thế nên e mới mạn phép hỏi bác tối ưu nó lên thôi ^^, chứ e thì chẳng dám đâm vào đây, đầu e còn mềm lắm. Hì hì ^^
  • 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


#15 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 13 April 2011 - 10:04 PM

Bạn thử cái này xem sao!
(defun c:Xapxi()
(setvar "osmode" 0) (setvar "cmdecho" 0)
(setq e1 (car (entsel "\nCho duong: "))
nd (getint "\nCho so khoang chia: ")
ds1 (acet-geom-vertex-list e1)
)
(command "Area" "o" e1)
(setq Chdai (getvar "Perimeter") S0 (getvar "Area")
ni 0 ld (/ Chdai nd) l0 0 dsdiem '()
)
(While (< l0 (+ 0.001 Chdai))
(setq dsdiem (append dsdiem (list (vlax-curve-getPointAtDist e1 l0)))
l0 (+ l0 ld)
)
)
(command "Spline")
(Foreach pt dsdiem (command pt)) (command "" "" "")
(setq e2 (entlast) ds2 (acet-geom-vertex-list e2))
(entdel e2)
(command "pline")(Foreach pt ds2 (command pt))(command "")
(setq e2 (entlast) s2 (vlax-curve-getarea e2))
(print (list s0 s2 "Sai so la: % " (/ (- s0 s2) s0 0.01)))
(princ)
)

Ghi chú: Với "ARC" Bạn chuyển qua Poly rồi hãy chạy c:Xapxi với Spline thì thôi!

Cám ơn bạn. Mình đã thử, Lisp chạy tốt nhưng chưa đúng với điều mình mong muốn.
Điều mình muốn đầu tiên là khống chế diện tích, sau đó là số đoạn chia càng ít càng tốt (tức là độ dài mỗi line tạo thành càng lớn càng tốt) và khoảng cách lớn nhất từ line đến đường cong càng nhỏ càng tốt. Khoảng cách từ đỉnh line đến đường cong có thể tùy nhập nhưng thường <=4cm
Trước đây mình có thể nghĩ ra những giải thuật hóc búa nhưng bây giờ có vẻ như bí thật rồi
  • 0

#16 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 13 April 2011 - 11:27 PM

Cám ơn bạn. Mình đã thử, Lisp chạy tốt nhưng chưa đúng với điều mình mong muốn.
Điều mình muốn đầu tiên là khống chế diện tích, sau đó là số đoạn chia càng ít càng tốt (tức là độ dài mỗi line tạo thành càng lớn càng tốt) và khoảng cách lớn nhất từ line đến đường cong càng nhỏ càng tốt. Khoảng cách từ đỉnh line đến đường cong có thể tùy nhập nhưng thường <=4cm
Trước đây mình có thể nghĩ ra những giải thuật hóc búa nhưng bây giờ có vẻ như bí thật rồi

Chào tất cả các bác!
Theo dõi bài toán này từ đầu đến bây giờ, tôi xin góp vui mấy điều:
I. Trước hết, đây là một bài toán "xấp xỉ" thuộc loại... hay.
II. Qua nhiều lần trao đổi thì có thể tóm tắt đề toán như thế này: tìm một đường (C') xấp xỉ đường (C ) sao cho:
1) delta S(C'-C) <= delta Smax.
2) delta pi(C'-C) <= delta pmax.
3) Li >= Lmax.
III. Trước khi xét nó ở dạng tổng quát, hãy xét 1 trường hợp đặc biệt: (C ) là đường tròn.
1') Do tính đối xứng của đường tròn => đường (C') cũng đối xứng tâm, thậm chí có thể chọn (C') để S(C'-C)=0 => OK!
2') Điều kiện 1) và 2) nói chung là mâu thuẫn nhau, tuy có thể có trường hợp thỏa mãn cả 2.
3') Giả sử cả 1) và 2) đều OK => tồn tại đường (C') => có vô số đường (C') => bài toán vô định!
4') Giả sử khi 2) thỏa mãn thì 3) không thỏa mãn (và ngược lại) => bài toán vô nghiệm.
Kết luận: trong trường hợp tổng quát bài toán này có thể có nghiệm xác định, cũng có thể vô định, và cũng có thể vô nghiệm => để giải một bài toán thực tế không đòi hỏi quá chính xác mà "trần ai" như thế thì nên chăng ta có thể bớt đi một điều kiện.
Mạn phép góp vui, nếu có sơ hở đâu đó trong lập luận thì mong các bác góp ý. Chúc mọi người vui!
  • 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 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 14 April 2011 - 01:40 AM

Chào tất cả các bác!
Theo dõi bài toán này từ đầu đến bây giờ, tôi xin góp vui mấy điều:
I. Trước hết, đây là một bài toán "xấp xỉ" thuộc loại... hay.
II. Qua nhiều lần trao đổi thì có thể tóm tắt đề toán như thế này: tìm một đường (C') xấp xỉ đường (C ) sao cho:
1) delta S(C'-C) <= delta Smax.
2) delta pi(C'-C) <= delta pmax.
3) Li >= Lmax.
III. Trước khi xét nó ở dạng tổng quát, hãy xét 1 trường hợp đặc biệt: (C ) là đường tròn.
1') Do tính đối xứng của đường tròn => đường (C') cũng đối xứng tâm, thậm chí có thể chọn (C') để S(C'-C)=0 => OK!
2') Điều kiện 1) và 2) nói chung là mâu thuẫn nhau, tuy có thể có trường hợp thỏa mãn cả 2.
3') Giả sử cả 1) và 2) đều OK => tồn tại đường (C') => có vô số đường (C') => bài toán vô định!
4') Giả sử khi 2) thỏa mãn thì 3) không thỏa mãn (và ngược lại) => bài toán vô nghiệm.
Kết luận: trong trường hợp tổng quát bài toán này có thể có nghiệm xác định, cũng có thể vô định, và cũng có thể vô nghiệm => để giải một bài toán thực tế không đòi hỏi quá chính xác mà "trần ai" như thế thì nên chăng ta có thể bớt đi một điều kiện.
Mạn phép góp vui, nếu có sơ hở đâu đó trong lập luận thì mong các bác góp ý. Chúc mọi người vui!

Xét TH đơn giản là một cung tròn và kg ràng buộc độ dài line (như đầu bài mình đã nói - nhập vào hoặc độ dài hoặc khoảng cách chứ kg đồng thời), mình nghĩ bài toán luôn có nghiệm. Ở đây đk bài toán là khống chế diện tích và khoảng cách từ đỉnh line đến đg cong, còn độ dài đoạn thẳng càng dài càng tốt chứ kg bắt buộc. Mời các bạn xem hình :Hình đã gửi
Xét một khỏang cách h cho trước (màu vàng) ta luôn dựng đc hai tiếp tuyến về hai phía của cung tròn (màu đỏ). Lúc này ta chỉ xét trên cung tròn nhỏ giới hạn bởi hai tiếp tuyến vừa tạo. Tại hai tiếp tuyến này ta có thể dựng được hai đoạn thẳng giao nhau(màu xanh) tại đoạn màu vàng đồng thời chia cung tròn thành hai phần ngoài và trong và chúng bù nhau. Dựa vào độ dài hai tiếp tuyến ta có thể tính đc tối đa có bao nhiêu đoạn thẳng như thế và cái khó nhất chính là hai đoạn thẳng màu xanh chia cung tròn nhỏ thành hai phần diện tích bù nhau. Ý tưởng là vậy, nhưng viết thành lisp thì cũng kg dễ.
  • 0

#18 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 14 April 2011 - 07:44 AM

Cám ơn bạn. Mình đã thử, Lisp chạy tốt nhưng chưa đúng với điều mình mong muốn.
Điều mình muốn đầu tiên là khống chế diện tích, sau đó là số đoạn chia càng ít càng tốt (tức là độ dài mỗi line tạo thành càng lớn càng tốt) và khoảng cách lớn nhất từ line đến đường cong càng nhỏ càng tốt. Khoảng cách từ đỉnh line đến đường cong có thể tùy nhập nhưng thường <=4cm
Trước đây mình có thể nghĩ ra những giải thuật hóc búa nhưng bây giờ có vẻ như bí thật rồi

Chào Bạn 'TRUNGNGAMY'
Quả thật bài toán này như các Bạn khác đã nói là khó khăn, hôm qua Mình đã viết nhưng biết là chỉ đạt yêu cầu về DeltaS và theo p2 đó thì muốn có deltaS nhỏ thì phải cần nhiều đoạn nhỏ và như vậy thì với nghành địa chính của Bạn chắc không muốn tí nào, cũng có thể sau đó dùng phương pháp cứng hóa đường poly để nó ít đỉnh hơn nhưng như vậy thì phức tạp quá.
Bạn thử chạy chương trình này xem, gấp nên viết còn dài dòng miễn sao đạt được kết quả cho Bạn thì tốt, để chạy trước hết Bạn cần chuẩn bị bằng cách tạo 1 đường tựa dọc theo đường cong ban đầu (tức vẽ 1 poly mô phỏng trước bằng tay) sau đó máy sẽ dựa vào đường tựa đó để chính xác hơn theo yêu cầu deltaS. Như vậy khi chạy nó sẽ hỏi đầu tiên là đường cần xấp xỉ và thứ hai là đường tựa (Bạn bấm vào). Hơi phức tạp nhưng nếu đật được yêu cầu của bạn thì tốt.
Chúc may mắn!

(defun c:Xapxi1()
(setvar "osmode" 0) (setvar "cmdecho" 0)
(setq e1 (car (entsel "\nCho duong chinh: "))
e2 (car (entsel "\nCho duong tua: "))
)
(If e1 (setq eluu e1)(setq e1 eluu))
(If e2 (setq e2luu e2)(setq e2 e2luu))
(setq ds2 (acet-geom-vertex-list e2) ilan 1
dsldai '() i 1 nlan (1- (length ds2))
)
(Repeat nlan
(setq dsldai (append dsldai (list (distance (nth i ds2) (nth (1- i) ds2))))
i (1+ i)
)
)
(setq nd 20 dskq0 '() dskq '() ;nd (getint "\nCho so khoang chia: ")
s1 (vlax-curve-getarea e2)
)
(command "Area" "o" e1)
(setq Chdai (getvar "Perimeter") S0 (getvar "Area")
ldai0 (car dsldai) ni 0 ld (/ ldai0 nd) l0 0 dsdiem '()
)
(While (< l0 (+ 0.001 Ldai0))
(setq dsdiem (append dsdiem (list (vlax-curve-getPointAtDist e1 l0)))
l0 (+ l0 ld)
)
)
(setq d0 (car dsdiem) i -1 kcmin 1000000000.0)
(repeat 360
(setq i (1+ i) goc (/ (* i pi) 180) d1 (polar d0 goc 1000000.0) kc 0.0)
(command "line" d0 d1 "")
(setq e2 (entlast))
(Foreach pt dsdiem
(setq da (vlax-curve-getClosestPointTo e2 pt)
kc (+ kc (distance da pt))
)
)
(If (< kc kcmin)(setq kcmin kc gocmin goc damin da))
(entdel e2)
)
(grdraw d0 damin (* ilan 20))
(setq dcuoi (last dsdiem) dskq0 (append dskq0 (list (list d0 dcuoi d0 damin ldai0))))
;;;;;LAP LAI LAN 2
(Repeat (1- nlan)
(setq lxp (last (last dskq0)))
(If (= ilan (1- nlan))(setq ldai0 Chdai)(setq ldai0 (+ (nth ilan DsLdai) lxp)))
(setq ni 0 ld (/ (- ldai0 lxp) nd) l0 lxp dsdiem '() ilan (1+ ilan))
(While (< l0 (+ 0.001 Ldai0))
(setq dsdiem (append dsdiem (list (vlax-curve-getPointAtDist e1 l0)))
l0 (+ l0 ld)
)
)
(setq d0 (cadddr (last dskq0)) i -1 kcmin 1000000.0 igoc 0.5)
(repeat (fix (/ 360 igoc))
(setq i (1+ i) goc (/ (* i pi igoc) 180) d1 (polar d0 goc 1000000.0) kc 0)
(command "line" d0 d1 "")(setq e2 (entlast))
(Foreach pt dsdiem
(setq da (vlax-curve-getClosestPointTo e2 pt)
kc (+ kc (distance da pt))
)
)
(If (< kc kcmin)(setq kcmin kc gocmin goc damin da))
(entdel e2)
)
(grdraw d0 damin (* ilan 20))
(setq dcuoi (last dsdiem) dskq0 (append dskq0 (list (list d0 dcuoi d0 damin ldai0))))
)
(Foreach pt dskq0
(setq dskq (append dskq (list (caddr pt))))
)
(setq dskq (append dskq (list (last (acet-geom-vertex-list e1)))))
(command "Undo" "be")
(command "Pline") (Foreach pt dskq (command pt))(command "")
(setq s2 (vlax-curve-getarea (entlast))
chu (strcat "\nS0: " (rtos s0 2 2) "\nS1: " (rtos s1 2 2)
" Sai so duong tua: " (rtos (/ (- s0 s1) s0 0.01) 2 2) "%\nS2: " (rtos s2 2 2)
" Sai so duong KQ : " (rtos (/ (- s0 s2) s0 0.01) 2 2) "%")
)
(command "Undo" "e")
(princ chu) (princ)
)

Ghi chú: Bạn cần vẽ đường tựa sao cho gần đúng nhất với đường mà Bạn mong muốn - Máy sẽ chạy trên đường tựa này nên Bạn chọn đường tựa càng tốt thì kết quả càng nhanh. - Mình chưa hiểu hết ý của Bạn về đoạn nói về cung tròn nhưng mình nghĩ nếu các đường cần xấp xỉ chỉ là cung tròn thì có thể đơn giản bài toán hơn nhiều, ở đây xét đường Spline nên phức tạp hơn. - Nếu đơn giản hóa bớt 1 số điều kiện thì bài toán sẽ dễ giải quyết hơn nhưng không biết về địa chính có cho phép không.- Chương trình Mình viết nếu chạy trên Cad2010 thì sẽ gặp 1 rắc rối nhỏ ở biến "area" nếu cad07 về trước thì không sao.
  • 0

#19 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 14 April 2011 - 09:38 AM

Chào Bạn 'TRUNGNGAMY'
Quả thật bài toán này như các Bạn khác đã nói là khó khăn, hôm qua Mình đã viết nhưng biết là chỉ đạt yêu cầu về DeltaS và theo p2 đó thì muốn có deltaS nhỏ thì phải cần nhiều đoạn nhỏ và như vậy thì với nghành địa chính của Bạn chắc không muốn tí nào, cũng có thể sau đó dùng phương pháp cứng hóa đường poly để nó ít đỉnh hơn nhưng như vậy thì phức tạp quá.
Bạn thử chạy chương trình này xem, gấp nên viết còn dài dòng miễn sao đạt được kết quả cho Bạn thì tốt, để chạy trước hết Bạn cần chuẩn bị bằng cách tạo 1 đường tựa dọc theo đường cong ban đầu (tức vẽ 1 poly mô phỏng trước bằng tay) sau đó máy sẽ dựa vào đường tựa đó để chính xác hơn theo yêu cầu deltaS. Như vậy khi chạy nó sẽ hỏi đầu tiên là đường cần xấp xỉ và thứ hai là đường tựa (Bạn bấm vào). Hơi phức tạp nhưng nếu đật được yêu cầu của bạn thì tốt.
Chúc may mắn!

(defun c:Xapxi1()
(setvar "osmode" 0) (setvar "cmdecho" 0)
(setq e1 (car (entsel "\nCho duong chinh: "))
e2 (car (entsel "\nCho duong tua: "))
)
(If e1 (setq eluu e1)(setq e1 eluu))
(If e2 (setq e2luu e2)(setq e2 e2luu))
(setq ds2 (acet-geom-vertex-list e2) ilan 1
dsldai '() i 1 nlan (1- (length ds2))
)
(Repeat nlan
(setq dsldai (append dsldai (list (distance (nth i ds2) (nth (1- i) ds2))))
i (1+ i)
)
)
(setq nd 20 dskq0 '() dskq '() ;nd (getint "\nCho so khoang chia: ")
s1 (vlax-curve-getarea e2)
)
(command "Area" "o" e1)
(setq Chdai (getvar "Perimeter") S0 (getvar "Area")
ldai0 (car dsldai) ni 0 ld (/ ldai0 nd) l0 0 dsdiem '()
)
(While (< l0 (+ 0.001 Ldai0))
(setq dsdiem (append dsdiem (list (vlax-curve-getPointAtDist e1 l0)))
l0 (+ l0 ld)
)
)
(setq d0 (car dsdiem) i -1 kcmin 1000000000.0)
(repeat 360
(setq i (1+ i) goc (/ (* i pi) 180) d1 (polar d0 goc 1000000.0) kc 0.0)
(command "line" d0 d1 "")
(setq e2 (entlast))
(Foreach pt dsdiem
(setq da (vlax-curve-getClosestPointTo e2 pt)
kc (+ kc (distance da pt))
)
)
(If (< kc kcmin)(setq kcmin kc gocmin goc damin da))
(entdel e2)
)
(grdraw d0 damin (* ilan 20))
(setq dcuoi (last dsdiem) dskq0 (append dskq0 (list (list d0 dcuoi d0 damin ldai0))))
;;;;;LAP LAI LAN 2
(Repeat (1- nlan)
(setq lxp (last (last dskq0)))
(If (= ilan (1- nlan))(setq ldai0 Chdai)(setq ldai0 (+ (nth ilan DsLdai) lxp)))
(setq ni 0 ld (/ (- ldai0 lxp) nd) l0 lxp dsdiem '() ilan (1+ ilan))
(While (< l0 (+ 0.001 Ldai0))
(setq dsdiem (append dsdiem (list (vlax-curve-getPointAtDist e1 l0)))
l0 (+ l0 ld)
)
)
(setq d0 (cadddr (last dskq0)) i -1 kcmin 1000000.0 igoc 0.5)
(repeat (fix (/ 360 igoc))
(setq i (1+ i) goc (/ (* i pi igoc) 180) d1 (polar d0 goc 1000000.0) kc 0)
(command "line" d0 d1 "")(setq e2 (entlast))
(Foreach pt dsdiem
(setq da (vlax-curve-getClosestPointTo e2 pt)
kc (+ kc (distance da pt))
)
)
(If (< kc kcmin)(setq kcmin kc gocmin goc damin da))
(entdel e2)
)
(grdraw d0 damin (* ilan 20))
(setq dcuoi (last dsdiem) dskq0 (append dskq0 (list (list d0 dcuoi d0 damin ldai0))))
)
(Foreach pt dskq0
(setq dskq (append dskq (list (caddr pt))))
)
(setq dskq (append dskq (list (last (acet-geom-vertex-list e1)))))
(command "Undo" "be")
(command "Pline") (Foreach pt dskq (command pt))(command "")
(setq s2 (vlax-curve-getarea (entlast))
chu (strcat "\nS0: " (rtos s0 2 2) "\nS1: " (rtos s1 2 2)
" Sai so duong tua: " (rtos (/ (- s0 s1) s0 0.01) 2 2) "%\nS2: " (rtos s2 2 2)
" Sai so duong KQ : " (rtos (/ (- s0 s2) s0 0.01) 2 2) "%")
)
(command "Undo" "e")
(princ chu) (princ)
)

Ghi chú: Bạn cần vẽ đường tựa sao cho gần đúng nhất với đường mà Bạn mong muốn - Máy sẽ chạy trên đường tựa này nên Bạn chọn đường tựa càng tốt thì kết quả càng nhanh. - Mình chưa hiểu hết ý của Bạn về đoạn nói về cung tròn nhưng mình nghĩ nếu các đường cần xấp xỉ chỉ là cung tròn thì có thể đơn giản bài toán hơn nhiều, ở đây xét đường Spline nên phức tạp hơn. - Nếu đơn giản hóa bớt 1 số điều kiện thì bài toán sẽ dễ giải quyết hơn nhưng không biết về địa chính có cho phép không.- Chương trình Mình viết nếu chạy trên Cad2010 thì sẽ gặp 1 rắc rối nhỏ ở biến "area" nếu cad07 về trước thì không sao.

Cám ơn bạn nhưng kg thể vẽ đc đường tựa bạn ạ. Nếu vẽ đc đường tựa thì dùng nó luôn chứ kg cần CT. TH mình đưa ra cung tròn là để giải quyết bài toán từ từ, đầu tiên là cung tròn, sau đó đến các thứ phức tạp hơn.
Bạn thử viết theo hướng mình gợi ý giúp. Cho trước khoảng cách (<=h là đc), khống chế diện tích (S-S<=0.1) và vẽ các đoạn thẳng càng lớn càng tốt. Tuy nhiên, mình vẫn chưa nghĩ ra đc cách dựng đg màu xanh sao cho diện tích trong và ngoài bù nhau, có thể kiến thức hình học phẳng mình đã quên rồi.
Lúc này mình cũng hơi lớn tuổi nên khả năng trừu tượng hóa vđ cho ra giải thuật đã giảm đáng kể, thêm nữa là mình kém về vl nên kg thể nhanh và đẹp như các bạn (mình cũng đã chứng kiến một số bạn viết lisp rất nhanh và hay)
  • 0

#20 TRUNGNGAMY

TRUNGNGAMY

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 401 Bài viết
Điểm đánh giá: 91 (tàm tạm)

Đã gửi 14 April 2011 - 01:27 PM

Hình đã gửi
Nhân đây nhờ các bạn giải giúp bài toán như hình vẽ. Cho cung tròn AB tâm O bk R. Dựng điểm C sao cho tổng diện tích màu vàng = màu đỏ. Cám ơn cac bạn
  • 0