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

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

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

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

  • Vote tăng 1

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

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

  • Vote tăng 4

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
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.

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
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 đề...

  • Vote tăng 5

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
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.

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

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.

  • Vote tăng 2

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
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.

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

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

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
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) "")
)

  • Vote tăng 1

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
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))

  • Vote tăng 5

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
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.

  • Vote tăng 1

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
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:

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

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.com/upfiles/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!

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
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.com/upfiles/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.

  • Vote tăng 3

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
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)

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
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.com/forum/index.php?showtopic=9791

http://www.cadviet.com/forum/index.php?showtopic=9227

http://www.cadviet.com/forum/index.php?showtopic=8598

................................................................................

......

Chúc bạn vui khi tham gia diễn đà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

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.com/upfiles/QUYHOACH.dwg

Nhờ các anh em giúp giúp.

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
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.com/upfiles/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))
   )
 )  
)

  • Vote tăng 1

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
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.

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
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.

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
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?

 

Đây là dữ liệu của một đường PL gồm một đoạn thẳng và một đoạn cong. Chú ý rằng mỗi đỉnh PL đều có mã DXF 42. Nếu giá trị mã này khác 0 thì phân đoạn ngay sau đỉnh đó là đoạn cong.

((-1 . ) (0 . LWPOLYLINE) (330 .

7ef69cf8>) (5 . 224F32) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 .

CAODODAYCONG) (100 . AcDbPolyline) (90 . 3) (70 . 0) (43 . 0.0) (38 . 0.0) (39

. 0.0) (10 2391.15 -3135.52) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 2464.21

-3061.75) (40 . 0.0) (41 . 0.0) (42 . -0.475185) (10 2609.54 -3075.87) (40 .

0.0) (41 . 0.0) (42 . 1.92085) (210 0.0 0.0 1.0))

 

Lệnh truy cập dữ liệu của một đối tượng:

;Ham xem du lieu doi tuong phuc

(defun C:OBDT(/ ent)

(setq ent (car(entsel "Chon doi tuong phuc : ")))

(princ "\n")

(while (/= (cdr(assoc 0 (entget ent))) "SEQEND")

(princ (entget ent))

(setq ent(entnext ent))

(princ "\n")

)

(princ (entget ent))(princ)

)

;Truy du lieu doi tuong

(defun C:OBDT1(/ ent)

(setq ent (car(entsel "Chon doi tuong : ")))

(princ "\n")

(princ (entget ent))

(princ)

)

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
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.

Bạn tham khảo bài viết về mảng trên afralisp.net

hoặc Selection Objects phần Selecting with Filters

  • Vote tăng 1

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
Bạn tham khảo bài viết về mảng trên afralisp.net

hoặc Selection Objects phần Selecting with Filters

Cảm ơn anh gia bách rất nhiều. Anh cho Tue_NV hỏi thêm là khi thao tác qua ActiveX với method, cụ thể là Getpoint Method có 1 chổ mà Tue_NV không hiểu và không sao làm được đó là cấu trúc và cú pháp của Getpoint Method

 

RetVal = GetPoint([Point][, Prompt])

 

Object

 

Utility

The object or objects this method applies to.

 

Point

 

Variant (three-element array of doubles); input-only; optional

The 3D WCS coordinates specifying the relative base point.

 

Prompt

 

Variant (string); input-only; optional

The text used to prompt the user for input.

 

RetVal

 

Variant (three-element array of doubles)

The 3D WCS coordinates of the point the AutoCAD user has selected.

 

Mình đã viết như sau : (vla-getpoint '(0 0 0) "\n Nhap point :")

và mình hiểu rằng điều đó là sai vì chưa hiểu đúng và đầy đủ định nghĩa là Varriant

 

Mong anh giabach và mọi người chỉ giúp và có thể cho 1 ví dụ nhỏ thôi về cái này để Tue_NV có thể hiểu hơn 1 chút về Activex

Cảm ơn anh giabach cùng mọi người.

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
cấu trúc và cú pháp của Getpoint Method

RetVal = GetPoint([Point][, Prompt])

Chào Tue_NV

Bạn có thể tham khảo ví dụ duới đây về vla-getpoint (vla-addline).

(defun c:test (/ doc Util pt1 pt2)

(vl-load-com)

(setq doc (vla-get-activeDocument (vlax-get-acad-object))

Util (vla-get-utility doc))

 

(setq pt1 (vla-getpoint Util nil "\nDiem dau : "))

(setq pt2 (vla-getpoint Util pt1 "\nDiem cuoi : "))

; ve Line

(vla-addline (vla-get-ModelSpace doc) pt1 pt2)

)

  • Vote tăng 1

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
Đây là dữ liệu của một đường PL gồm một đoạn thẳng và một đoạn cong. Chú ý rằng mỗi đỉnh PL đều có mã DXF 42. Nếu giá trị mã này khác 0 thì phân đoạn ngay sau đỉnh đó là đoạn cong.

((-1 . ) (0 . LWPOLYLINE) (330 .

7ef69cf8>) (5 . 224F32) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 .

CAODODAYCONG) (100 . AcDbPolyline) (90 . 3) (70 . 0) (43 . 0.0) (38 . 0.0) (39

. 0.0) (10 2391.15 -3135.52) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 2464.21

-3061.75) (40 . 0.0) (41 . 0.0) (42 . -0.475185) (10 2609.54 -3075.87) (40 .

0.0) (41 . 0.0) (42 . 1.92085) (210 0.0 0.0 1.0))

 

Lệnh truy cập dữ liệu của một đối tượng:

;Ham xem du lieu doi tuong phuc

(defun C:OBDT(/ ent)

(setq ent (car(entsel "Chon doi tuong phuc : ")))

(princ "\n")

(while (/= (cdr(assoc 0 (entget ent))) "SEQEND")

(princ (entget ent))

(setq ent(entnext ent))

(princ "\n")

)

(princ (entget ent))(princ)

)

;Truy du lieu doi tuong

(defun C:OBDT1(/ ent)

(setq ent (car(entsel "Chon doi tuong : ")))

(princ "\n")

(princ (entget ent))

(princ)

)

Cách của dangbaoduy1982 không hay bằng hàm này đâu. Đó là hàm (vla-getbulge object index), hàm sẽ trả về độ lồi của đoạn cong trên polyline. G288 tạo vòng lặp với n là số node, khi nào (vla-getbulge object index) /= 0 có nghĩa là tại index đó có đoạn cong (arc)

Từ lâu, thiep đã biết hàm này, bây giờ thiep mới reply, không biết có muộn màng không?

  • Vote tăng 1

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

×