Đến nội dung


Hình ảnh
- - - - -

Hỏi về thông tin của Spline và một số hàm VL..,Vlax..


  • Please log in to reply
40 replies to this topic

#1 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 07 April 2009 - 11:02 AM

Các bác trên diễn đàn cho Tue_NV hỏi một chút về thông tin của Spline và một số hàm về vl..., vlax...,
vì có nhiều chổ chưa biết lắm. Mong các bác chỉ giúp.
- Khi vẽ một đường Spline. Đánh lệnh Li (List) để lấy thông tin Spline thì có một chổ là :

Parametric Range: Start 0.00000
End 9294.67247

Parametric Range này là gì vậy các bác và lại có Start 0.00000 và End 9294.67247 nữa.
Thật tình là Tue_NV chưa hiểu chổ này.
Và khi vận dụng hàm vlax-curve-getEndParam như sau :
(setq ss (car(entsel "\n Chon Spline :")))
Sau khi chọn Spline trên -> đánh lệnh (vlax-curve-getendparam ss) -> ta lại thu được kết quả là 9294.67

Tue_NV chưa hiểu dược bản chất của Parametric Range này là gì? và hàm (vlax-curve-getendparam ss) nghĩa là gì?
Mong các bác chỉ giúp.

Command: li LIST
Select objects: 1 found

Select objects:
SPLINE Layer: "aa"
Space: Model space
Handle = 341F03
Length: 9426.05651
Order: 4
Properties: Planar, Non-Rational, Non-Periodic
Parametric Range: Start 0.00000
End 9294.67247
Number of control points: 5
Control Points: X = 11603.08343, Y = 155307.73581, Z =
0.00000
X = 12516.88624, Y = 156316.90295, Z =
.......
Cảm ơn mọi người thật nhiều
  • 1

#2 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

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

Đã gửi 07 April 2009 - 01:35 PM

Có thể hiểu nôm na như sau:

Lưu trữ dữ liệu một đường cong thường rất phức tạp (nhất là đường cong trơn mịn). Để lưu trữ đường cong, người ta không thể lưu tất cả các điểm thuộc đường cong đó được, mà phải thông qua một hàm số toán học nào đó, ví dụ là f(t). Hàm f(t) trong trường hợp tổng quát của AutoCAD phức tạp và nó như thế nào thì chúng ta cũng không cần quan tâm. Vấn đề chúng ta quan tâm là phương trình: d = f(t) trong đó d là distance (length at current point) và t là parameter.

Chúng ta dùng các hàm chuyển xuôi vlax-curve-getDistAtParam để tìm d từ t, và dùng hàm chuyển ngược vlax-curve-getParamAtDist để tìm t từ d.

Khi chúng ta vẽ một spline mới, hàm f(t) được xây dựng và ghi lại vào dữ liệu của spline. Nếu chúng ta dùng lệnh trim để chặt ngắn bớt thì rõ ràng hàm f(t) không thay đổi (vì vẫn là phương trình như vậy), mà chỉ có miền giá trị của t thay đổi. Khi đó, chúng ta sẽ có giá trị start parameter và end parameter khác ban đầu. Và cũng lẽ tương tự, chúng ta không thể extend được spline (vì như vậy cad phải xây dựng lại hàm f(t)).

Nếu ai quan tâm muốn tìm hiểu sâu thêm cách biểu diễn đường cong spline của CAD nói chung và ACAD nói riêng, có thể tìm kiếm trên google với từ khóa Curve Local Parameter
  • 4

#3 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 07 April 2009 - 02:15 PM

Có thể hiểu nôm na như sau:

Lưu trữ dữ liệu một đường cong thường rất phức tạp (nhất là đường cong trơn mịn). Để lưu trữ đường cong, người ta không thể lưu tất cả các điểm thuộc đường cong đó được, mà phải thông qua một hàm số toán học nào đó, ví dụ là f(t). Hàm f(t) trong trường hợp tổng quát của AutoCAD phức tạp và nó như thế nào thì chúng ta cũng không cần quan tâm. Vấn đề chúng ta quan tâm là phương trình: d = f(t) trong đó d là distance (length at current point) và t là parameter.

Chúng ta dùng các hàm chuyển xuôi vlax-curve-getDistAtParam để tìm d từ t, và dùng hàm chuyển ngược vlax-curve-getParamAtDist để tìm t từ d.

Khi chúng ta vẽ một spline mới, hàm f(t) được xây dựng và ghi lại vào dữ liệu của spline. Nếu chúng ta dùng lệnh trim để chặt ngắn bớt thì rõ ràng hàm f(t) không thay đổi (vì vẫn là phương trình như vậy), mà chỉ có miền giá trị của t thay đổi. Khi đó, chúng ta sẽ có giá trị start parameter và end parameter khác ban đầu. Và cũng lẽ tương tự, chúng ta không thể extend được spline (vì như vậy cad phải xây dựng lại hàm f(t)).

Nếu ai quan tâm muốn tìm hiểu sâu thêm cách biểu diễn đường cong spline của CAD nói chung và ACAD nói riêng, có thể tìm kiếm trên google với từ khóa Curve Local Parameter

Em xin cảm ơn bác Hoành đã hồi âm lại cho em.
Trong phương trình: d = f(t) trong đó d là distance (length at current point) và t là parameter
d : chính là distance : được hiểu là khoảng cách
t là parameter : biến t Param này là em chưa hiểu được bản chất của nó bác Hoành ạ.
Chúng ta dùng các hàm chuyển xuôi vlax-curve-getDistAtParam để tìm d từ t, và dùng hàm chuyển ngược vlax-curve-getParamAtDist để tìm t từ d. => Cái này chính là cái em chưa hiểu về nó đấy bác ạ.
Nếu có thể, em mong bác bỏ chút ít thời gian để giải thích một chút để em hiểu thêm về nó.
Có thể 1 ví dụ nho nhỏ cũng được.
Mong bác Hoành và mọi người trên diễn đàn chỉ giúp cho Tue_NV
Tue_NV cảm ơn các bác nhiều lắm.
  • 0

#4 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 08 April 2009 - 02:08 PM

Chúng ta dùng các hàm chuyển xuôi vlax-curve-getDistAtParam để tìm d từ t, và dùng hàm chuyển ngược vlax-curve-getParamAtDist để tìm t từ d. => Cái này chính là cái em chưa hiểu về nó đấy bác ạ.

1- Trước hết, bạn cần nắm các khái niệm:
Curve: đường cong nói chung, có thể là line, pline, spline, circle, arc, ellipse...
Param: như anh Hoành đã giải thích
Dist: chiều dài từ điểm start đến điểm đang xét (đo dọc theo curve chứ không phải theo "đường chim bay")

2- Làm 1 ví dụ đơn giản, từ "trực quan sinh động" đến "tư duy trừu tượng":
Vẽ 1 pline ABC (1 curve-obj có 2 segments là đoạn thẳng), với AB= 200, BC= 100. Áp dụng các hàm vlax-curve-xxxx ta có:
(vlax-curve-getParamAtPoint curve-obj A) -> 0
(vlax-curve-getParamAtPoint curve-obj B ) -> 1
(vlax-curve-getParamAtPoint curve-obj C) -> 2
Nhận xét: với pline trên giá trị param được xác định theo vertex (đỉnh), bắt đầu từ 0 là startParam và 2 là endParam.

Xác định 1 điểm D là trung điểm của BC, bạn kiểm tra sẽ thấy:
(vlax-curve-getParamAtPoint curve-obj D) -> 1.5
Xác định điểm E, có BE/BC = 0.75, kết quả:
(vlax-curve-getParamAtPoint curve-obj E) -> 1.75
Nhận xét: phần thập phân của param lấy tỷ lệ phần trăm theo chiều dài của segment đang xét

Kiểm tra tiếp:
(vlax-curve-getDistAtParam curve-obj 1.75) -> 275.0
(vlax-curve-getParamAtDist curve-obj 275.0) -> 1.75


Hiểu được chỗ này tức là vướng mắc của bạn đã đuợc giải toả

3- Với mỗi loại curve, cách xác định param có khác nhau:
- Với line, giá trị param chính là giá trị dist
- Với circle, giá trị param tính theo góc radian
- Spline phức tạp nhất vì Acad phải tính toán nội suy để cho curve trơn tru. Nói chung, endParam nhỏ hơn dist một chút.

Tiếp tục thử như trên với các loại curve khác và các hàm vlax-curve-xxxx khác, hy vọng rằng bạn sẽ tự nghiệm ra bản chất vấn đề...
  • 5

#5 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 08 April 2009 - 10:13 PM

1- Trước hết, bạn cần nắm các khái niệm:
Curve: đường cong nói chung, có thể là line, pline, spline, circle, arc, ellipse...
Param: như anh Hoành đã giải thích
Dist: chiều dài từ điểm start đến điểm đang xét (đo dọc theo curve chứ không phải theo "đường chim bay")

Tiếp tục thử như trên với các loại curve khác và các hàm vlax-curve-xxxx khác, hy vọng rằng bạn sẽ tự nghiệm ra bản chất vấn đề...

Chào các bác,
Nhân thể bác Tue_NV đề cập đến các hàm vl ..... vlax......, thú thực mình cũng định té nước theo mưa hỏi ké các bác về mấy anh cu này. Quả thực mình cũng đã cố gắng tìm hiểu qua các lisp trên diễn đàn cũng như trong Help và help developer của cad , nhưng thấy nó rậm rì rắc rối quá chừng. Lọ mọ hoài mà vẫn có nhiều điểm chưa thông.
Mình xin hỏi một chút về mấy cái hàm bác nguyenhoanh đã dùng trong cái lisp tìm giao điểm của các đối tượng:
1/- (vla-IntersectWith ob1 ob2 acExtendNone) : cái hàm này mình tìm trong help và help developer của cad chả thấy nó đâu cả. Các bác có thể chỉ giùm mình chỗ nó núp để mình mần mò nó xem sao chứ thấy ức lắm. Nhất là chỗ cái tham số acExtendNone ấy. Đọc chữ thì hiểu đại khái ý là tìm cái giao điểm nhưng không cho nối dài các đối tượng, nhưng cụ thể ra răng thì tịt ngóm. Mình cũng đã thấy có bạn lại dùng với tham số acExtendBoth thì hiểu là tìm giao điểm mà cả hai đối tượng đều được giãn dài thoải mái. Vậy thế nếu chỉ cho phép giãn dài một đối tượng thì sao??? Vả lại như bác NguyenHoanh đã giải thích ở topic này là Spline không cho giãn dài thế thì cái tham số acExtendBoth sẽ dùng thế nào???
2/- (vlax-safearray-get-u-bound g 1): cái hàm này trong help developer có nói đến, song mình chưa hiểu rõ lắm. Cái đối tượng safearray nghĩa là gì??? Có phải là một đối tượng phải khép kín không??? Cái vốn tiếng Anh còn lỏng nên hiểu chưa được tỏ tường, mong các bác giúp đỡ.

Kể ra thì còn nhiều nhiều cái muốn hỏi lắm lắm. Nhưng thôi thì nhai kỹ no lâu, các bác cứ giúp mình gỡ mấy cái xơ này đã. Ngẫm cho thủng, tiêu hóa kỹ rồi lại hỏi tiếp các bác nhể.

Mong các bác luôn mạnh khỏe, vững tay chèo chống để cái đám lỏng vốn như mình có chỗ nhờ cậy.
Cám ơn các bác nhiều.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#6 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

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

Đã gửi 08 April 2009 - 11:33 PM

1. Help viết đầy đủ đấy chứ bác. Bác đừng tra từ vla-IntersectWith vì tiền tố vla- là tự động được thêm vào khi thao tác qua ActiveX với tất cả các method, event hay property của ACAD object.
Đây là diễn giải của method IntersectWith:

Gets the points where one object intersects another object in the drawing.
Signature
RetVal = object.IntersectWith(IntersectObject, ExtendOption)
Object
All Drawing Objects (Except Pviewport and PolygonMesh)
The object this method applies to.
IntersectObject
Object, input-only;
The object can be one of All Drawing Objects.
ExtendOption
AcExtendOption enum; input-only
This option specifies if none, one or both, of the objects are to be extended in order to attempt an intersection.
acExtendNone: Does not extend either object.
acExtendThisEntity: Extends the base object.
acExtendOtherEntity: Extends the object passed as an argument.
acExtendBoth: Extends both objects.
RetVal
Variant (array of doubles)
The array of points where one object intersects another object in the drawing.

Remarks
If the two objects do not intersect, no data is returned. You can request the point of intersection that would occur if one or both of the objects were extended to meet the other. For example, in the following illustration, Line1 is the base object from which this method was called and line3 is the object passed as a parameter. If the ExtendOption passed is acExtendThisEntity, point A is returned as the point where line1 would intersect line3 if line1 were extended. If the ExtendOption is acExtendOtherEntity, no data is returned because even if line3 were extended, it would not intersect line1.
If the intersection type is acExtendBothEntities and line2 is passed as the parameter entity, point B is returned. If the ExtendOption is acExtendNone and line2 is the parameter entity, no data is returned.

Bác đọc đoạn trên chắc chắn bác hiểu vấn đề ngay. Còn vấn đề về spline thì vẫn vậy thôi bác, kể cả cho dù Extend option là gì đi nữa thì nếu không giao vào phần trong của spline thì kết quả trả về vẫn là nil vì spline trong ACAD là không thể extend.

2. Safearray là một kiểu biến. Nếu như kiểu biến integer, real, string,... là đơn lẻ từng giá trị thì safearray là một mảng chứa các (nhiều) giá trị. Sở dĩ có kiểu biến này là vì ngôn ngữ autolisp không có biến kiểu mảng (array) vì lisp chỉ xử lý chủ yếu trên biến kiểu danh sách (list). Do vậy không tương thích với một số phần mềm được viết chủ yếu dưới ngôn ngữ C++. Để khắc phục điều này, autolisp 'sáng tạo' kiểu riêng tương ứng của autolisp là safearray. Do safearray cũng tương đồng với list nên lisp có sẵn hàm để chuyển đổi từ safearray qua list: vlax-safearray->list. Khi chuyển đổi ngược lại, không có hàm sẵn (vì nhiều trường hợp không đổi được bởi miền giá trị của list rộng hơn safearray và list không có index như safearray) chúng ta phải tự viết mã. Bác có thể search trên google với từ khóa "convert list to safearray" để có code.
Về hàm vlax-safearray-get-u-bound, trong help đã nói rõ rồi: Returns the upper boundary (end index) of a dimension of an array. Dịch nôm na: trả về giá trị cận trên của miền (chỉ số cuối) của kích thước của một mảng.
Lý giải: Giả sử biến g là một mảng 3 chiều thể hiện các ô nhớ như bên dưới:
- [1][2][3][4]
- [3][4][5]
- [0][1][2][3][4][5][6]
vậy thì:
biến này có tổng thể 4+3+7=14 ô nhớ tất cả. Địa chỉ các ô nhớ này là g[1][1],g[1][2],g[1][3]g[1][4]; g[2][3], g[2][4], g[2][5]; g[3][0], g[3][1],...g[3][6].
và:
(vlax-safearray-get-u-bound g 1) bằng 4 (chỉ số cuối của mảng con thứ nhất)
(vlax-safearray-get-u-bound g 2) bằng 5 (chỉ số cuối của mảng con thứ hai)
(vlax-safearray-get-u-bound g 3) bằng 6 (chỉ số cuối của mảng con thứ ba)

(vlax-safearray-get-l-bound g 1) bằng 1 (chỉ số đầu của mảng con thứ nhất)
(vlax-safearray-get-l-bound g 2) bằng 3 (...)
(vlax-safearray-get-l-bound g 3) bằng 0 (...)

Nói thì phức tạp nhưng bác làm theo ví dụ trong help thì sẽ hiểu ngay.
  • 2

#7 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 22 April 2009 - 03:46 PM

1. Help viết đầy đủ đấy chứ bác. Bác đừng tra từ vla-IntersectWith vì tiền tố vla- là tự động được thêm vào khi thao tác qua ActiveX với tất cả các method, event hay property của ACAD object.
Đây là diễn giải của method IntersectWith:
Bác đọc đoạn trên chắc chắn bác hiểu vấn đề ngay. Còn vấn đề về spline thì vẫn vậy thôi bác, kể cả cho dù Extend option là gì đi nữa thì nếu không giao vào phần trong của spline thì kết quả trả về vẫn là nil vì spline trong ACAD là không thể extend.

2. Safearray là một kiểu biến. Nếu như kiểu biến integer, real, string,... là đơn lẻ từng giá trị thì safearray là một mảng chứa các (nhiều) giá trị. Sở dĩ có kiểu biến này là vì ngôn ngữ autolisp không có biến kiểu mảng (array) vì lisp chỉ xử lý chủ yếu trên biến kiểu danh sách (list). Do vậy không tương thích với một số phần mềm được viết chủ yếu dưới ngôn ngữ C++. Để khắc phục điều này, autolisp 'sáng tạo' kiểu riêng tương ứng của autolisp là safearray. Do safearray cũng tương đồng với list nên lisp có sẵn hàm để chuyển đổi từ safearray qua list: vlax-safearray->list. Khi chuyển đổi ngược lại, không có hàm sẵn (vì nhiều trường hợp không đổi được bởi miền giá trị của list rộng hơn safearray và list không có index như safearray) chúng ta phải tự viết mã. Bác có thể search trên google với từ khóa "convert list to safearray" để có code.
Về hàm vlax-safearray-get-u-bound, trong help đã nói rõ rồi: Returns the upper boundary (end index) of a dimension of an array. Dịch nôm na: trả về giá trị cận trên của miền (chỉ số cuối) của kích thước của một mảng.
Lý giải: Giả sử biến g là một mảng 3 chiều thể hiện các ô nhớ như bên dưới:
- [1][2][3][4]
- [3][4][5]
- [0][1][2][3][4][5][6]
vậy thì:
biến này có tổng thể 4+3+7=14 ô nhớ tất cả. Địa chỉ các ô nhớ này là g[1][1],g[1][2],g[1][3]g[1][4]; g[2][3], g[2][4], g[2][5]; g[3][0], g[3][1],...g[3][6].
và:
(vlax-safearray-get-u-bound g 1) bằng 4 (chỉ số cuối của mảng con thứ nhất)
(vlax-safearray-get-u-bound g 2) bằng 5 (chỉ số cuối của mảng con thứ hai)
(vlax-safearray-get-u-bound g 3) bằng 6 (chỉ số cuối của mảng con thứ ba)

(vlax-safearray-get-l-bound g 1) bằng 1 (chỉ số đầu của mảng con thứ nhất)
(vlax-safearray-get-l-bound g 2) bằng 3 (...)
(vlax-safearray-get-l-bound g 3) bằng 0 (...)

Nói thì phức tạp nhưng bác làm theo ví dụ trong help thì sẽ hiểu ngay.

Chào bác Hoành
Thú thực là đọc bài của bác mình cũng vỡ ra được nhiều vấn đề về phương pháp đọc tài liệu. Mình cũng hiểu được một số hàm vlax, vl. Tuy nhiên về các biến và tham số của nó thì vẫn còn mù mịt lắm. Vi dụ như cái biến safearray chẳng hạn. Biết rằng đó là biến mảng nhưng chả biết cấu trúc cái mảng ấy ra sao cả.
Mình nhờ bác giải thích giùm thêm một chút nhé.
Lấy cái lisp tìm giao điểm của bác làm ví dụ cụ thể bác nhé.
Mình đã thử debug nó trong quá trình chạy để xem kết quả thì thấy như sau:
1/- Sau khi lisp chạy hết dòng (setq g (vlax-variant-value(vla-IntersectWith ob1 ob2 acExtendNone))). Lúc này biến g trả về giá trị là một biến mảng # (safearray ....) . Chả biết cái ...... này là cái gì cả.
Khi dùng hàm (vlax-safearray-get-u-bound g 1) thì nếu các đối tượng có cắt nhau lisp sẽ trả về các giá trị dương 2,3,5... (cận trên miền thứ nhất của biến g có giá trị là 2, 3, 5...) nhưng nếu chúng không cắt nhau lisp sẽ trả về giá trị -1 (cận trên của miền thứ nhất của biến g sẽ lấy giá trị -1). Do vậy mình hiểu được cái hàm điều kiện của bác . Thế nhưng:
Khi mình dùng hàm (setq g (vlax-safearray->list g)) thì biến g trả về một list các tọa độ của các điểm giao nhau khi các đối tượng có cắt nhau (list các tham số chứa trong biến mảng g), còn khi chúng không cắt nhau thì lisp trả về Error. Trong cái list này mình chả tìm thấy các già trị 2, 3, 5 của hàm (vlax-safearray-get-u-bound g 1) nằm ở vị trí nào cả nên mình chả hiểu là các giá trị này nằm ở đâu trong cái biến mảng g đó.
2/- Theo mình hiểu thì hàm (vlax-safearray->list g) là để chuyển cái biến g ở dạng mảng về thành dạng list với trật tự các tham số của nó theo đúng thứ tự lần lượt từng mảng con một như bác đã ví dụ ở bài trên. Như vậy ắt hẳn phải có các giá trị 2, 3, 5 của hàm (vlax-safearray-get-u-bound g 1) trong cái list kết quả của hàm (vlax-safearray->list g) chứ bác nhỉ? Vậy mà ở đây mình lại không thấy, thế thì cấu trúc cái biến mảng này ra sao và có cách nào xác định nó không. Không hiểu được nó thì cái giá trị -1, 2,3,5 ..... của hàm (vlax-safearray-get-u-bound g 1) cũng chả hiểu tại sao mà có bác ạ

Bác có thể giải thích rõ hơn cho mình với nhé.
Thank bác trướ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.

#8 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 13 May 2009 - 07:49 AM

Tue_NV có một bài toán này loay hoay mãi mà vẫn chưa tìm ra cách giải quyết vấn đề. Mong các bác trên diễn đàn giúp đỡ.

Bài toán : Có 1 Curve (Spline hay 1 Polyline). Giả sử có 1 điểm A nằm trên Curve đó. Từ điểm A trên Curve đó vẽ 1 đường vuông góc (d) với tiếp tuyến tại A của Curve. Xác định 1 điểm nằm trên đường vuông góc với tiếp tuyến (d) cách điểm A 1 khoảng là L cho trước. Làm sao để tìm được điểm này. Mình muốn sử dụng Lisp các bác à

Mong các bác trên diễn đàn chỉ dùm Tue_NV.
Xin cảm ơn các bác thật nhiều
  • 0

#9 q288

q288

    biết lệnh fillet

  • Members
  • PipPipPipPip
  • 209 Bài viết
Điểm đánh giá: 164 (tàm tạm)

Đã gửi 13 May 2009 - 12:45 PM

Tue_NV có một bài toán này loay hoay mãi mà vẫn chưa tìm ra cách giải quyết vấn đề. Mong các bác trên diễn đàn giúp đỡ.

Bài toán : Có 1 Curve (Spline hay 1 Polyline). Giả sử có 1 điểm A nằm trên Curve đó. Từ điểm A trên Curve đó vẽ 1 đường vuông góc (d) với tiếp tuyến tại A của Curve. Xác định 1 điểm nằm trên đường vuông góc với tiếp tuyến (d) cách điểm A 1 khoảng là L cho trước. Làm sao để tìm được điểm này. Mình muốn sử dụng Lisp các bác à

Mong các bác trên diễn đàn chỉ dùm Tue_NV.
Xin cảm ơn các bác thật nhiều


Mình nghĩ ct này có thể giúp giải bài toán trên (dùng với spline và pline thẳng), đối với pline cong (có arc) thì trong đoạn arc cho kết quả ko đúng. Tiện đây cũng hỏi luôn xem có bạn nào có ct hay hàm nào nhận biết đc một đoạn trong pline là thẳng hay cong ko?


(defun thgoc(ent pt1 kc / obj pt2)
(setq obj (vlax-ename->vla-object ent)
pt2 (vlax-curve-getPointAtParam obj (fix (vlax-curve-getParamAtPoint obj pt1))))
(if pt2
(list (polar pt1 (+ (angle pt2 pt1) (* 0.5 pi)) kc)
(polar pt1 (- (angle pt2 pt1) (* 0.5 pi)) kc))
nil)
)

(defun c:test()
(setq l (thgoc (car (entsel "\nChon duong cong:"))
(getpoint "\nChon diem tren dg cong:")
(getreal "\nKhoang cach toi dg cong:")))
(setvar "OSMODE" 0)
(command "line" (car l) (last l) "")
)

  • 1

#10 gia_bach

gia_bach

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 1432 Bài viết
Điểm đánh giá: 1425 (rất tốt)

Đã gửi 13 May 2009 - 01:33 PM

Tue_NV có một bài toán này loay hoay mãi mà vẫn chưa tìm ra cách giải quyết vấn đề. Mong các bác trên diễn đàn giúp đỡ.
Bài toán : Có 1 Curve (Spline hay 1 Polyline). Giả sử có 1 điểm A nằm trên Curve đó. Từ điểm A trên Curve đó vẽ 1 đường vuông góc (d) với tiếp tuyến tại A của Curve. Xác định 1 điểm nằm trên đường vuông góc với tiếp tuyến (d) cách điểm A 1 khoảng là L cho trước. Làm sao để tìm được điểm này. Mình muốn sử dụng Lisp các bác à
.......

Chào Tue_NV .
Bạn thử LISP này nhé.
Hàm trả về danh sách (List) 2 điểm (2 bên Curve) vuông góc với Curve tại điểm cho trước thuộc Curve.
cEnt : Cad entity
pt: điểm
dis: khoảng cách cho trước

(defun get_point_curve (cEnt pt dis / param ang)
(if (setq param (vlax-curve-getParamAtPoint cEnt pt))
(progn
(setq ang (- (angle '(0 0 0)
(vlax-curve-getFirstDeriv cEnt param))
(/ pi 2))
)
(list (polar pt ang dis) (polar pt ang (- dis)) )
)
)
)


ví dụ minh họa vẽ các đường thẳng vuông góc với Curve
(defun c:vg(/ cEnt dist ctc kcach pt lst_pt)
(if (and (setq cEnt (car (entsel "\nSelect Curve: "))
dist 0
ctc 500;(getdist "Nhap buoc nhay :" )
kcach 50;(getdist "Nhap khoang cach :" )
)
(member (cdr (assoc 0 (entget cEnt))) '("LINE" "POLYLINE" "LWPOLYLINE" "SPLINE" "ARC"))
)
(while (< dist (vlax-curve-getDistAtParam cEnt (vlax-curve-getEndParam cEnt)))
(setq pt (vlax-curve-getPointAtDist cEnt dist)
dist (+ dist ctc)
)
(if (setq lst_pt (get_point_curve cEnt pt kcach))
(entmake (list (cons 0 "LINE") (cons 10 (car lst_pt)) (cons 11 (cadr lst_pt)) ) )
)
)
(alert "No Curve Selected !"))
(princ))

  • 5

#11 q288

q288

    biết lệnh fillet

  • Members
  • PipPipPipPip
  • 209 Bài viết
Điểm đánh giá: 164 (tàm tạm)

Đã gửi 13 May 2009 - 02:02 PM

Chào Tue_NV .
Bạn thử LISP này nhé.
Hàm trả về danh sách (List) 2 điểm (2 bên Curve) vuông góc với Curve tại điểm cho trước thuộc Curve.
cEnt : Cad entity
pt: điểm
dis: khoảng cách cho trước


Bạn Gia_Bach có nhiều ct hay thiệt, giải quyết cả arc, circle, spline, pline. Nhờ ct của bạn mà mình mới hiểu hàm vlax-curve-getFirstDeriv làm cái công việc gì.
thanks.
  • 1

#12 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

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

Đã gửi 14 May 2009 - 11:39 PM

Bạn Gia_Bach có nhiều ct hay thiệt, giải quyết cả arc, circle, spline, pline. Nhờ ct của bạn mà mình mới hiểu hàm vlax-curve-getFirstDeriv làm cái công việc gì.
thanks.


Em cũng công nhận bác Gia bach có nhiều Lisp hay lắm. :mellow:
Không biết đến chừng nào nội công của em mới thâm hậu như các bác cao thủ trên diễn đàn nữa. :mellow:
  • 0

#13 VoHoan

VoHoan

    biết lệnh move

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

Đã gửi 17 May 2009 - 08:52 PM

Chào các bác e đang tìm hiểu về cách viết lisp nhưng có ít tài liệu để nghiên cứu nên gặp rất nhiều khó, không biết bác nào có tài liệu nào hay cho em xin với.
Hiện này em đang có tài liệu này: http://www.cadviet.c...Auto_Lisp_2.pdf và một số lisp có sẵn. À cho em hỏi luôn kinh nghiệm để học cách viết lisp hiệu quả cao. Mong sự hồi âm sớm.
Xin cám ơn!
  • 0

#14 q288

q288

    biết lệnh fillet

  • Members
  • PipPipPipPip
  • 209 Bài viết
Điểm đánh giá: 164 (tàm tạm)

Đã gửi 17 May 2009 - 09:55 PM

Chào các bác e đang tìm hiểu về cách viết lisp nhưng có ít tài liệu để nghiên cứu nên gặp rất nhiều khó, không biết bác nào có tài liệu nào hay cho em xin với.
Hiện này em đang có tài liệu này: http://www.cadviet.c...Auto_Lisp_2.pdf và một số lisp có sẵn. À cho em hỏi luôn kinh nghiệm để học cách viết lisp hiệu quả cao. Mong sự hồi âm sớm.
Xin cám ơn!


Trước hết cần nắm vững ngôn ngữ Lisp, ý nghĩa và cách ứng dung các hàm của nó, cái này đọc help là đủ rồi. Sau đó bạn xem cách ng khác viết lisp để giải quyết bài toán đặt ra , rồi tự tìm cách viết khác hay hơn , hiệu quả hơn, ngắn gọn hơn, hoặc thuật toán chính xác hơn để giải bài toán đó. Cái này đòi hỏi phải xem nhiều chương trình, nhiều ví dụ.
Nói chung học ngôn ngữ lập trình cũng giống như học ngoại ngữ vậy, phải đọc hiểu trước rồi mới viết sau. Viết ct cũng đòi hỏi phải có chút năng khiếu, sự siêng năng và lòng đam mê nữa.
Chúc bạn sớm thành Pro.
  • 3

#15 trần văn lực

trần văn lực

    biết zoom

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

Đã gửi 20 May 2009 - 09:30 AM

Có thể hiểu nôm na như sau:

Lưu trữ dữ liệu một đường cong thường rất phức tạp (nhất là đường cong trơn mịn). Để lưu trữ đường cong, người ta không thể lưu tất cả các điểm thuộc đường cong đó được, mà phải thông qua một hàm số toán học nào đó, ví dụ là f(t). Hàm f(t) trong trường hợp tổng quát của AutoCAD phức tạp và nó như thế nào thì chúng ta cũng không cần quan tâm. Vấn đề chúng ta quan tâm là phương trình: d = f(t) trong đó d là distance (length at current point) và t là parameter.

Chúng ta dùng các hàm chuyển xuôi vlax-curve-getDistAtParam để tìm d từ t, và dùng hàm chuyển ngược vlax-curve-getParamAtDist để tìm t từ d.

Khi chúng ta vẽ một spline mới, hàm f(t) được xây dựng và ghi lại vào dữ liệu của spline. Nếu chúng ta dùng lệnh trim để chặt ngắn bớt thì rõ ràng hàm f(t) không thay đổi (vì vẫn là phương trình như vậy), mà chỉ có miền giá trị của t thay đổi. Khi đó, chúng ta sẽ có giá trị start parameter và end parameter khác ban đầu. Và cũng lẽ tương tự, chúng ta không thể extend được spline (vì như vậy cad phải xây dựng lại hàm f(t)).

Nếu ai quan tâm muốn tìm hiểu sâu thêm cách biểu diễn đường cong spline của CAD nói chung và ACAD nói riêng, có thể tìm kiếm trên google với từ khóa Curve Local Parameter


Chào bác hoành,em đang phải in nhiều bản vẽ bằng lệnh view mà phải in từng bản một rất lâu bác có lisp nào để in một lúc dược nhiều bản vẽ không cho em xin với. em cảm ơn bác nhỉều. (luctran84@yahoo.com.vn)
  • 0

#16 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 20 May 2009 - 11:28 AM

Chào bác hoành,em đang phải in nhiều bản vẽ bằng lệnh view mà phải in từng bản một rất lâu bác có lisp nào để in một lúc dược nhiều bản vẽ không cho em xin với. em cảm ơn bác nhỉều. (luctran84@yahoo.com.vn)

Chào bạn Trần Văn Lực,
Vấn đề bạn hỏi đã được thảo luận khá nhiều trên diễn đàn. Bạn nên chịu khó tìm kiếm trên diễn đàn kỹ trước khi pót câu hỏi của mình. Hơn nữa bạn hãy pót câu hỏi đúng với chủ đề của nó sẽ được sự quan tâm của nhiều người có cùng mối quan tâm như bạn hơn và sẽ thu được nhiều ý kiến bổ ích hơn bạn ạ.
Rất mong bạn lưu ý cho các lần pót bài sau này để đỡ làm phiền những người khác bạn nhé.
Bạn hãy vào đây để xem cách giải quyết vấn đề của bạn:
http://www.cadviet.c...?showtopic=9791
http://www.cadviet.c...?showtopic=9227
http://www.cadviet.c...?showtopic=8598
................................................................................
......
Chúc bạn vui khi tham gia 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.

#17 thiep

thiep

    biết dimbaseline

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

Đã gửi 30 May 2009 - 01:22 PM

Nhân nói về mảng, tôi có bài toán mà tôi vẫn chưa gải được, tôi nghĩ nếu sử dụng mảng thì có thể giải được
như sau:
Có 1 khu đất đã đánh giá các loại cây rừng loại A, B, C. Làm sao tạo hàm lisp để phân phân vùng loại A, B, C.
Bản vẽ như sau:
http://www.cadviet.c...es/QUYHOACH.dwg
Nhờ các anh em giúp giúp.
  • 0

#18 q288

q288

    biết lệnh fillet

  • Members
  • PipPipPipPip
  • 209 Bài viết
Điểm đánh giá: 164 (tàm tạm)

Đã gửi 30 May 2009 - 07:33 PM

Nhân nói về mảng, tôi có bài toán mà tôi vẫn chưa gải được, tôi nghĩ nếu sử dụng mảng thì có thể giải được
như sau:
Có 1 khu đất đã đánh giá các loại cây rừng loại A, B, C. Làm sao tạo hàm lisp để phân phân vùng loại A, B, C.
Bản vẽ như sau:
http://www.cadviet.c...es/QUYHOACH.dwg
Nhờ các anh em giúp giúp.


Không hiểu mảng bạn nói là gì và ý bạn muốn là giải bài toán hay chỉ đơn giản là từ cái hình bên trái vẽ thành cái hình giống như bên phải,
nếu chỉ là vẽ thì mình có làm cái lisp sau, kết quả ra cũng giống, chỉ có hình thức hơi khác:

(defun c:qh()
(setq ss (ssget '((0 . "TEXT")))
ss1 (ssadd)
ss3 (ssadd))
(setvar "osmode" 0)

(repeat (sslength ss)
(setq ent (ssname ss 0)
eget (entget ent)
tt11 (cdr (assoc 11 eget))
tt1 (cdr (assoc 1 eget)))
(cond ((= tt1 "A") (setvar "cecolor" "1"))
((= tt1 "B") (setvar "cecolor" "2"))
((= tt1 "C") (setvar "cecolor" "3")))
(command "rectang" (polar (polar tt11 0 2.5) (/ pi 2) -2.5)
(polar (polar tt11 0 -2.5) (/ pi 2) 2.5))
(setq elast (entlast))
(command "explode" elast)
(setq enext (entnext elast))
(while enext (ssadd enext ss1) (setq enext (entnext enext)))
(ssdel ent ss)
)

(while (> (sslength ss1) 0)
(setq ent (ssname ss1 0)
eget (entget ent)
tt10 (cdr (assoc 10 eget))
tt11 (cdr (assoc 11 eget))
ttg (polar tt10 (angle tt10 tt11) (/ (setq dis (distance tt10 tt11)) 2))
ss2 (ssget "c" (polar ttg (* -0.25 pi) (* 0.1 dis)) (polar ttg (* 0.75 pi) (* 0.1 dis))))

(if (and (= 2 (sslength ss2))
(= (cdr (assoc 62 (entget (ssname ss2 0)))) (cdr (assoc 62 (entget (ssname ss2 1))))))
(progn
(command "erase" ss2 "")
(ssdel (ssname ss2 0) ss1)
(ssdel (ssname ss2 1) ss1))
(progn
(ssadd ent ss3)
(ssdel ent ss1))
)
)
)

  • 1

#19 thiep

thiep

    biết dimbaseline

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

Đã gửi 01 June 2009 - 12:41 PM

Không hiểu mảng bạn nói là gì và ý bạn muốn là giải bài toán hay chỉ đơn giản là từ cái hình bên trái vẽ thành cái hình giống như bên phải,
nếu chỉ là vẽ thì mình có làm cái lisp sau, kết quả ra cũng giống, chỉ có hình thức hơi khác:

Ý mình như thế này:
Tạo mảng có M chiều, mỗi chiều có N phần tử, mỗi phần tử là 1 ký tự, A hoặc B hoặc C ...
So sánh các phần tử gần kề kể cả trên và dưới. Nếu giá trị 2 phần tử này khác nhau thì vẽ 1 vạch phân cách. sau đó nối chúng lại nhau thành 1 đường Pline phân cách.
Cảm ơn q288 nhiều.
  • 0

#20 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 August 2009 - 01:47 PM

2. Safearray là một kiểu biến. Nếu như kiểu biến integer, real, string,... là đơn lẻ từng giá trị thì safearray là một mảng chứa các (nhiều) giá trị. Sở dĩ có kiểu biến này là vì ngôn ngữ autolisp không có biến kiểu mảng (array) vì lisp chỉ xử lý chủ yếu trên biến kiểu danh sách (list). Do vậy không tương thích với một số phần mềm được viết chủ yếu dưới ngôn ngữ C++. Để khắc phục điều này, autolisp 'sáng tạo' kiểu riêng tương ứng của autolisp là safearray. Do safearray cũng tương đồng với list nên lisp có sẵn hàm để chuyển đổi từ safearray qua list: vlax-safearray->list. Khi chuyển đổi ngược lại, không có hàm sẵn (vì nhiều trường hợp không đổi được bởi miền giá trị của list rộng hơn safearray và list không có index như safearray) chúng ta phải tự viết mã. Bác có thể search trên google với từ khóa "convert list to safearray" để có code.
Về hàm vlax-safearray-get-u-bound, trong help đã nói rõ rồi: Returns the upper boundary (end index) of a dimension of an array. Dịch nôm na: trả về giá trị cận trên của miền (chỉ số cuối) của kích thước của một mảng.

Lý giải: Giả sử biến g là một mảng 3 chiều thể hiện các ô nhớ như bên dưới:
- [1][2][3][4]
- [3][4][5]
- [0][1][2][3][4][5][6]
vậy thì:
biến này có tổng thể 4+3+7=14 ô nhớ tất cả. Địa chỉ các ô nhớ này là g[1][1],g[1][2],g[1][3]g[1][4]; g[2][3], g[2][4], g[2][5]; g[3][0], g[3][1],...g[3][6].
và:
(vlax-safearray-get-u-bound g 1) bằng 4 (chỉ số cuối của mảng con thứ nhất)
(vlax-safearray-get-u-bound g 2) bằng 5 (chỉ số cuối của mảng con thứ hai)
(vlax-safearray-get-u-bound g 3) bằng 6 (chỉ số cuối của mảng con thứ ba)

(vlax-safearray-get-l-bound g 1) bằng 1 (chỉ số đầu của mảng con thứ nhất)
(vlax-safearray-get-l-bound g 2) bằng 3 (...)
(vlax-safearray-get-l-bound g 3) bằng 0 (...)

Nói thì phức tạp nhưng bác làm theo ví dụ trong help thì sẽ hiểu ngay.

Chào bác Hoành và mọi người trên diễn đàn

Tue_NV đã xem qua các ví dụ trong Help. Nhưng các ví dụ trong Help quá ít.
Nếu có thể, bác Hoành và mọi người có thể cho 1 ví dụ nho nhỏ thôi để mình có thể hiểu thêm một chút về mảng safearray và vấn đề lý giải trên của bác Hoành

Tue_NV xin cảm ơn nhiều lắm.
  • 0