Chuyển đến nội dung
Diễn đàn CADViet
Đăng nhập để thực hiện theo  
Doan Van Ha

[Nhờ tìm lỗi] Cad tính tiếp tuyến tại điểm cuối curve bị sai

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

Nhờ mọi người tìm lỗi và/hoặc giải tích vì sao đường vuông góc với curve tại điểm cuối trọng 2 curve đỏ bị sai, còn 2 curve xanh thì đúng (2 curve xanh là 2 curve đỏ đã break đoạn cuối).
Dùng lisp vẽ đính kèm:


(defun C:HA()
 (setq ent (car (entsel "\nPick entity: ")))
 (setq pt (getpoint "\nPick point: "))
 (setq goc (angle '(0 0 0) (vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt))))
 (entmake (list (cons 0 "LINE") '(100 . "AcDbEntity") (cons 10 pt) (cons 11 (polar pt (+ goc (/ pi 2)) 100.0)))))

 


Bản vẽ đính kèm:
Image:
image.png

Error_Sample.dwg

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

debug thấy

(vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt)) = (1.26979e-016 9.16744e-015 0.0)

gần đạt đến giới hạn độ chính xác của số thực => góc có sai số lớn

thêm đoạn code sau:

    (setq g (entget ent) lp (vl-remove-if-not ''((x) (=(car x) 10)) g))

ta được

lp = ((10 3568.58 447.895 0.0) (10 3579.31 450.769 0.0) (10 3599.03 456.054 0.0) (10 3606.68 492.683 0.0) (10 3640.52 520.304 0.0) (10 3825.43 440.735 0.0) (10 3825.43 440.735 0.0) (10 3825.43 440.735 0.0))

3 điểm control cuối gần = nhau. Tăng độ chính xác
    (setq d56 (mapcar '- (cdr (nth 6 lp)) (cdr (nth 5 lp))) d67 (mapcar '- (cdr (nth 7 lp)) (cdr (nth 6 lp))))

d56 = (0.0 0.0 0.0), d67 = (0.0 4.54747e-013 0.0)

ta thấy điểm 5 và 6 trùng nhau, điểm 7 cách không đáng kể

Không thể bắt nearest vào đoạn gần cuối

 

  • Like 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
30 phút trước, ndtnv đã nói:

debug thấy

(vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt)) = (1.26979e-016 9.16744e-015 0.0)

gần đạt đến giới hạn độ chính xác của số thực => góc có sai số lớn

thêm đoạn code sau:

    (setq g (entget ent) lp (vl-remove-if-not ''((x) (=(car x) 10)) g))

ta được

lp = ((10 3568.58 447.895 0.0) (10 3579.31 450.769 0.0) (10 3599.03 456.054 0.0) (10 3606.68 492.683 0.0) (10 3640.52 520.304 0.0) (10 3825.43 440.735 0.0) (10 3825.43 440.735 0.0) (10 3825.43 440.735 0.0))

3 điểm control cuối gần = nhau. Tăng độ chính xác
    (setq d56 (mapcar '- (cdr (nth 6 lp)) (cdr (nth 5 lp))) d67 (mapcar '- (cdr (nth 7 lp)) (cdr (nth 6 lp))))

d56 = (0.0 0.0 0.0), d67 = (0.0 4.54747e-013 0.0)

ta thấy điểm 5 và 6 trùng nhau, điểm 7 cách không đáng kể

Không thể bắt nearest vào đoạn gần cuối

 

Cám ơn anh ndtnv! Tôi muốn hỏi thêm:
1. Curve màu đỏ là curve tôi vẽ spline xong rồi break 1 đoạn gần cuối thì cớ sự gì nó sinh ra vây?
2. 2 cuvers đỏ là bản copy của nhau nhưng tiếp tuyến tại điểm cuối cũng khác nhau?
3. Có cách gì để xử lý nhằm lấy tiếp tuyến đúng với mọi điểm của curve khô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

1. Ngoài khả năng của tôi vì tôi đã tìm hiểu cách tìm phương trình Spline nhưng có nhiều cách khác nhau thường là mô phỏng theo hàm mũ.

     y = Σai.x^i  Chỗ này có nói cách tìm hệ số ai

  Tôi thấy cách tính ở đây hợp lý hơn nhưng không có hướng dẫn cách tìm các hệ số:

     x = Σai.t^i

     y = Σbi.t^i

2 . Sai số của số thực khoảng 5e-16 nên theo tôi khi copy ra thì do

(vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt) xấp xỉ sai số đó

=> các control point thay đổi với giá trị tuyệt đối gần như nhau nhưng tương đối sẽ khác nhau

=> góc khác nhau

3. Vì độ chính xác số thực của máy tính như vậy nên một số trường hợp đặt biệt như bài này không làm được

  • Like 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

Kiểm tra thử, chiều dài curve là 297.34 đơn vị vẽ thì trong khoảng 5 đơn vị vẽ cuối cùng là không thể lấy góc tiếp tuyến. Một khoảng cách quá lớn!!!
(vlax-curve-getdistatparam ent (vlax-curve-getendparam ent)) = 297.34

(setq pt (vlax-curve-getpointatdist ent 292.34)) = (3820.83 402.536 0.0)

(vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt)) >> error: bad argument type: numberp: nil

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
21 giờ trước, Doan Van Ha đã nói:

Kiểm tra thử, chiều dài curve là 297.34 đơn vị vẽ thì trong khoảng 5 đơn vị vẽ cuối cùng là không thể lấy góc tiếp tuyến. Một khoảng cách quá lớn!!!
(vlax-curve-getdistatparam ent (vlax-curve-getendparam ent)) = 297.34

(setq pt (vlax-curve-getpointatdist ent 292.34)) = (3820.83 402.536 0.0)

(vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent pt)) >> error: bad argument type: numberp: nil

Ứng với bản vẽ bác đính kèm, param của điểm cuối là 294.03769646133196, tại giá trị này thì Cad bị lỗi.

Nhưng nếu làm tròn 3 số lẻ (e-3) 294.038 thì có thể lấy tiếp tuyến được.

Không biết lỗi này có phụ thuộc phiên bản CAD hay không?!  Tôi dùng CAD 2016.

(defun C:HA()
 (setq ent (car (entsel "\nPick entity: ")))

; (setq endParam (vlax-curve-getendParam ent)) ; endParam = 294.03769646133196
  (setq endParam 294.038)
  (setq pt (vlax-curve-getPointAtParam ent endparam))
  (setq goc (angle '(0 0 0) (vlax-curve-getFirstDeriv ent endparam)))
  (entmake (list (cons 0 "LINE") '(100 . "AcDbEntity") (cons 10 pt) (cons 11 (polar pt (+ goc (/ pi 2)) 100.0))))
  ; (setq endParam 294.0376) error
  )

 

  • Like 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

Lisp của bac không sai. 

Cad cũng không có lỗi. Nó tính đúng.

Vấn đề ở đường spline kia. nó có 2 đỉnh số 6 và 7 trùng nhau. điểm số 8 nó lệch xuống 1 chút.

Nếu bác đo góc 2 điểm số 7 và 8 thì nó gần vuông góc với kêt quả lisp chạy ra được. Chỉ là không quan sát được nên bác nghĩ lisp lỗi thôi.

  • Like 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
Đăng nhập để thực hiện theo  

×