Chuyển đến nội dung
Diễn đàn CADViet
  • Thông báo

    • Nguyen Hoanh

      CADViet đã hoàn tất nâng cấp   14/09/2017

      Chào các bạn, CADViet đã hoàn tất việc nâng cấp lên phiên bản mới. Tất cả các chức năng đã hoạt động theo kỳ vọng của ban quản trị. Nếu có vấn đề gì cần phản hồi, các bản post ở đây nhé: Trân trọng, Nguyễn Hoành.
ndtnv

Dùng mảng (array) trong lisp

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

ndtnv    397

Dùng safearray trong LISP tiện lợi hơn nhiều so với dùng list

VD khi viết bảng TKCT, nếu dùng biến thường thì mỗi loại thép phải đặt cho 1 tên.

Như vậy, ta khó dùng các vòng lặp để gán và lấy biến. Nếu dùng list thì việc gán trị rất phức tạp.

Giải pháp là dùng safearray .

Sau đây là hướng dẫn dùng safearray dịch từ help của acad

Creates a safearray

(vlax-make-safearray type '(l-bound . u-bound) ['(lbound . u-bound)...)]

1 array có thể có tối đa 16 chiều. Các biến trong array được khởi tạo như sau :

Numbers

0

Strings

Zero-length string.

Booleans

:vlax-false

Object

nil

Variant

Uninitialized (vlax-vbEmpty)

Arguments

type

Kiểu của safearray được định theo các hằng số sau:

vlax-vbInteger (2) Integer

vlax-vbLong (3) Long integer

vlax-vbSingle (4) Single-precision floating-point number

vlax-vbDouble (5) Double-precision floating-point number

vlax-vbString (8) String

vlax-vbObject (9) Object

vlax-vbBoolean (11) Boolean

vlax-vbVariant (12) Variant

Số nguyên trong ngoặc là giá trị các hằng số. Bạn nên dùng các hằng số thay cho các số nguyên vì có thể thay đổi trong các phiên bản khác của AutoCAD.

'(l-bound . ubound)

Chỉ số dưới và trên của 1 chiều.

Return Values

The safearray created.

Examples

Tạo safearray 1 chiều l oại double bắt đầu từ chỉ số 0:

_$ (setq point (vlax-make-safearray vlax-vbDouble '(0 . 3)))

#<safearray...>

Dùng hàm vlax-safearray->list để thể hiện nội dung của safearray như 1 list:

_$ (vlax-safearray->list point)

(0.0 0.0 0.0 0.0)

Kết quả cho thấy mỗi phần tử trong array được khởi tạo là zero.

Tạo safearray 2 chiều l oại string bắt đầu từ chỉ số 1:

_$ (setq matrix (vlax-make-safearray vlax-vbString '(1 . 2) '(1 . 2) ))

#<safearray...>

  • 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
ndtnv    397

Để gán trị dùng các hàm

vlax-safearray-fill

vlax-safearray-put-element

Để lấy trị dùng

vlax-safearray-get-element

1 số hàm khác

vlax-safearray-get-dim

vlax-safearray-get-l-bound

vlax-safearray-get-ul-bound

Cách dùng xem help

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
thiep    263
Để gán trị dùng các hàm

vlax-safearray-fill

vlax-safearray-put-element ...

Cách dùng xem help

Chào bạn ndtnv, bài viết của bạn đã lâu, nhưng đề tài về safearray không cũ chút nào. Tôi đang học cách tạo 1 safearray từ 1 bảng List, nhưng tôi không hiểu gì về cách khai báo kiểu biến. Tôi đã đọc Help nhưng không rõ, Help viết quá ngắn gọn, và không ví dụ nhiều NDTNV có thể giải thích cho tôi cách khai báo từng kiểu cho từng trường hợp nhé:

0 Uninitialized (vlax-vbEmpty)

1 Contains no valid data (vlax-vbNull)

3 Long integer (vlax-vbLong)

4 Single-precision floating-point number (vlax-vbSingle)

5 Double-precision floating-point number (vlax-vbDouble)

9 Object (vlax-vbObject)

11 Boolean (vlax-vbBoolean)

Tôi có sưu tầm 1 Lisp do NguyenHoanh sưu tầm, gồm các hàm làm việc với Block, trong Lisp đó có Hàm

(defun list->variantArray (ptsList / arraySpace sArray)

(setq arraySpace

(vlax-make-safearray

vlax-vbdouble

(cons 0 (- (length ptsList) 1))

)

)

(setq sArray (vlax-safearray-fill arraySpace ptsList))

(vlax-make-variant sArray)

)

ptsList tôi nghĩ là 1 list của các tọa độ POINT (điểm chèn Block), nhưng khi tôi khai báo 1 list giống như thế thì máy cứ báo lỗi:

error: vlax-safearray-fill failed. Invalid initialization list. # ((390718.0 1.53408e+006 0.0) (390706.0 1.53409e+006 0.0) ....)

Nhờ bạn hướng dẫn giùm nhé. Trân trọng.

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
ndtnv    397
Chào bạn ndtnv, bài viết của bạn đã lâu, nhưng đề tài về safearray không cũ chút nào. Tôi đang học cách tạo 1 safearray từ 1 bảng List, nhưng tôi không hiểu gì về cách khai báo kiểu biến. Tôi đã đọc Help nhưng không rõ, Help viết quá ngắn gọn, và không ví dụ nhiều NDTNV có thể giải thích cho tôi cách khai báo từng kiểu cho từng trường hợp nhé:

0 Uninitialized (vlax-vbEmpty)

1 Contains no valid data (vlax-vbNull)

3 Long integer (vlax-vbLong)

4 Single-precision floating-point number (vlax-vbSingle)

5 Double-precision floating-point number (vlax-vbDouble)

9 Object (vlax-vbObject)

11 Boolean (vlax-vbBoolean)

Tôi có sưu tầm 1 Lisp do NguyenHoanh sưu tầm, gồm các hàm làm việc với Block, trong Lisp đó có Hàm

(defun list->variantArray (ptsList / arraySpace sArray)

(setq arraySpace

(vlax-make-safearray

vlax-vbdouble

(cons 0 (- (length ptsList) 1))

)

)

(setq sArray (vlax-safearray-fill arraySpace ptsList))

(vlax-make-variant sArray)

)

ptsList tôi nghĩ là 1 list của các tọa độ POINT (điểm chèn Block), nhưng khi tôi khai báo 1 list giống như thế thì máy cứ báo lỗi:

error: vlax-safearray-fill failed. Invalid initialization list. # ((390718.0 1.53408e+006 0.0) (390706.0 1.53409e+006 0.0) ....)

Nhờ bạn hướng dẫn giùm nhé. Trân trọng.

Lisp của bạn dùng chưa đúng cách nên có lỗi. Bạn phải post lên toàn bộ thì mới kiểm được.

 

Các kiểu biến:

vlax-vbInteger (2) Integer , trị khởi tạo = 0

- Số nguyên có độ dài 2 bytes, có giá trị –32,768 to +32,767

vlax-vbLong (3) Long integer , trị khởi tạo = 0

- Số nguyên có độ dài 4 bytes, có giá trị –2147483648 to +2147483647

vlax-vbSingle (4) Single-precision floating-point number , trị khởi tạo = 0.0

- Số thực chính xác đơn có độ dài 4 bytes

vlax-vbDouble (5) Double-precision floating-point number , trị khởi tạo = 0.0

- Số thực chính xác kép có độ dài 8 bytes

lax-vbString (8) String , trị khởi tạo = ""

- Kiểu chuỗi

9 Object (vlax-vbObject)

- Kiểu đối tượng

11 Boolean (vlax-vbBoolean)

- Kiểu Boolean gồm 2 giá trị là: nil và T

vlax-vbVariant (12) Variant , trị khởi tạo =

- Kiểu Variant

Vậy tùy theo mảng của bạn chứa kiểu nào, bạn khai báo kiểu tương ứng là số hay hằng.

VD (trong help) tạo 1 mảng double 3 phần tử ta có 2 cách khai báo:

(setq sa (vlax-make-safearray 5 '(0 . 2)))

hoặc là

(setq sa(vlax-make-safearray vlax-vbDouble '(0 . 2)))

Nếu bạn quen dùng chỉ số từ 1 thì có thể khai báo

(setq sa (vlax-make-safearray vlax-vbDouble '(1 . 3)))

 

Bạn nên dùng các VD trong help, đổi khai báo kiểu rồi chạy thử thì sẽ nắm vững hơn

 

Trong lisp trên, câu lệnh:

(setq arraySpace (vlax-make-safearray vlax-vbdouble (cons 0 (- (length ptsList) 1)) ) )

sẽ tạo 1 safearray có tên là arraySpace, kiểu double, số phần tử = số phần tử của ptsList

ptsList là 1 list có các phần tử kiểu double

Câu lệnh:

(setq sArray (vlax-safearray-fill arraySpace ptsList))

sẽ fill các phần tử của ptsList vào mảng arraySpace , sau đó gán cho sArray

  • 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
thiep    263
Lisp của bạn dùng chưa đúng cách nên có lỗi. Bạn phải post lên toàn bộ thì mới kiểm được.

 

...

ptsList là 1 list có các phần tử kiểu double

Câu lệnh:

(setq sArray (vlax-safearray-fill arraySpace ptsList))

sẽ fill các phần tử của ptsList vào mảng arraySpace , sau đó gán cho sArray

Ndtnv thân,

Đọc xong, tôi đã hiểu được 1 phần nào cái sArray này. Xin hỏi thêm:

Giả sử ptsList của tôi là 1 list 6 phần tử chứa tọa độ và tên của các text, đơn giản như sau:

(((1.0 1.0 0.0) "A") ((1.0 2.0 0.0) "B") ((1.0 3.0 0.0) "C")) ((2.0 1.0 0.0) "D") ((2.0 2.0 0.0) "E") ((2.0 3.0 0.0) "F")))

trong trường hợp này thì phải khai báo như thế nào?

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
ndtnv    397
Ndtnv thân,

Đọc xong, tôi đã hiểu được 1 phần nào cái sArray này. Xin hỏi thêm:

Giả sử ptsList của tôi là 1 list 6 phần tử chứa tọa độ và tên của các text, đơn giản như sau:

(((1.0 1.0 0.0) "A") ((1.0 2.0 0.0) "B") ((1.0 3.0 0.0) "C")) ((2.0 1.0 0.0) "D") ((2.0 2.0 0.0) "E") ((2.0 3.0 0.0) "F")))

trong trường hợp này thì phải khai báo như thế nào?

Bạn nên dùng 2 safearray riêng để chứa tọa độ và tên point

(setq point (vlax-make-safearray vlax-vbdouble  '(0 . 5) '(0 . 2)))
(setq name (vlax-make-safearray vlax-vbString   '(0 . 5) ))
(vlax-safearray-fill point (list '(1.0 1.0 0.0) '(1.0 2.0 0.0) '(1.0 3.0 0.0) '(2.0 1.0 0.0) '(2.0 2.0 0.0) '(2.0 3.0 0.0) ))
(vlax-safearray-fill name '("A" "B" "C" "D" "E" "F"))

Nếu dùng kiểu vlax-vbVariant thì phức tạp hơn nhiều

- Khai báo ptsList là 1 safearray

- Tạo safearray chứa tọa độ điểm, đổi thành kiểu variant

như trong hàm (defun list->variantArray () ...)

- Các tên điểm cũng đổi thành kiểu variant

- Đưa safearray của point vào ptsList

Nếu có thời gian, bạn hãy xem cách dùng safearray để lưu tọa độ trong AutoLISP Tutorial

  • 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

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


×