UCS Alert when setting active?

Discussion in 'AutoCAD' started by BillZ, Aug 10, 2004.

  1. BillZ

    BillZ Guest

    R2005:
    I was having trouble creating a new ucs with vla-add.
    I got the message:
    "; error: Automation Error. UCS X axis and Y axis are not perpendicular"

    So I searched the NG and found the post:
    http://discussion.autodesk.com/thread.jspa?messageID=3845216

    I created a new UCS at 0.0 origin as prescribed by Jeff Mishler:
    I then changed the origin to the point I wanted and changed the x and y vectors.

    All looked good until I made the new ucs active:

    (vlax-put *acaddoc* "activeucs" newucs)

    I got an AutoCAD alert box that I had to click an "okay" button that said "Non-perpendicular UCS X and Y axis; normalizing"

    Anyone know what is happening here?

    TIA

    Bill
     
    BillZ, Aug 10, 2004
    #1
  2. BillZ

    Jürg Menzi Guest

    Hi Bill
    Do you use x and y coordinates of a point? The vla-add operation requires
    xvector and yvector. The functions below normalizes point values to vectors:
    (MeVecNormalize (list Xcoord Ycoord 0.0))

    Code:
    ;
    ; == Function MeVecNormalize
    ; Normalizes Vec to unit length (1.0).
    ; Arguments [Type]:
    ;   Vec = Vector (list of 3 doubles) [LIST]
    ; Return [Type]:
    ;   > Normalized vector [LIST]
    ; Notes:
    ;   None
    ;
    (defun MeVecNormalize (Vec / VecCoe)
    (setq VecCoe (/ 1.0 (MeVecLen Vec)))
    (MeSetZero (mapcar '* Vec (list VecCoe VecCoe VecCoe)))
    )
    ;
    ; == Function MeSetZero
    ; Recursively eliminates floating point precision problems when values are
    ; aproximately 0.
    ; Arguments [Type]:
    ;   Lst = List or nested list of floating point numbers [LIST]
    ; Return [Type]:
    ;   > Normalized list [LIST]
    ; Notes:
    ;   None
    ;
    (defun MeSetZero (Lst)
    (mapcar
    '(lambda (l)
    (if (= (type l) 'LIST)
    (MeSetZero l)
    (if (and (> l (- 1E-13)) (< l 1E-13))
    0.0
    l
    )
    )
    ) Lst
    )
    )
    ;
    ; == Function MeVecLen
    ; Calculates length of a vector.
    ; Arguments [Type]:
    ;   Vec = Vector (list of 3 doubles) [LIST]
    ; Return [Type]:
    ;   > Length of the vector [REAL]
    ; Notes:
    ;   None
    ;
    (defun MeVecLen (Vec)
    (car
    (MeSetZero
    (list (sqrt (apply '+ (mapcar '(lambda (p) (* p p)) Vec))))
    )
    )
    )
    Cheers
     
    Jürg Menzi, Aug 11, 2004
    #2
  3. Rounding issues can really bite you when working on the UCS object. Search
    the VBA ng for a few threads on this subject in the last year or two. There
    was some code posted that was supposed to help greatly with the rounding
    issues.

    --
    R. Robert Bell


    Jürg,

    I have tried again using your function.
    Still get alert box when I set the UCS to active and when ever I zoom in to
    the area afterwards.

    This is what I am doing.

    (setq x_vec (MeVecNormalize (mapcar '- xdr bsp))
    y_vec (MeVecNormalize (mapcar '- ydr bsp))
    )
    ;with bsp being the WCS point coordinates for the origin that I want and xdr
    being the WCS point in the X direction and ydr the WCS point in the Y
    direction.

    I believe that (mapcar '- xdr bsp) is the way to get the vector, correct me
    if I'm wrong.

    Then I do this:
    (setq UCS_Tmp (vla-add *ucs_col*
    (vlax-3d-point '(0.0 0.0 0.0))
    (vlax-3d-point '(1.0 0.0 0.0))
    (vlax-3d-point '(0.0 1.0 0.0)) "TEMP")
    )
    (vla-put-Origin UCS_Tmp bspo) ;bspo is the point object.
    (vla-put-Xvector UCS_Tmp (vlax-3d-point x_vec))
    (vla-put-Yvector UCS_Tmp (vlax-3d-point y_vec))
    (vla-put-ActiveUCS *acaddoc* UCS_Tmp)

    This creates the UCS perfectly, the only problem is the alert box.

    Thanks for the help.

    Bill
     
    R. Robert Bell, Aug 11, 2004
    #3
  4. BillZ

    Jürg Menzi Guest

    Hi Bill

    Seems to be a precision problem as Robert says... solution:
    Code:
    (setq VecLst (MeCalcVecs bsp xdr ydr))
    ....
    (vla-put-Xvector UCS_Tmp (vlax-3d-point (car VecLst)))
    (vla-put-Yvector UCS_Tmp (vlax-3d-point (cadr VecLst)))
    ....
    
    ;
    ; == Function MeCalcVecs
    ; Calculates the two vectors for UCS by using the cross product.
    ; Arguments [Type]:
    ;   Ori = Origin point [LIST]
    ;   PtX = Point in X direction [LIST]
    ;   PtY = Point in Y direction [LIST]
    ; Return [Type]:
    ;   > Vector list '(Xvex Yvec) [LIST]
    ; Notes:
    ;   None
    ;
    (defun MeCalcVecs (Ori PtX PtY / CroPro PerVec X_Vect Y_Vect)
    (setq X_Vect (MeVecNormalize (mapcar '- PtX Ori))
    Y_Vect (MeVecNormalize (mapcar '- PtY Ori))
    CroPro (MeCrossProduct X_Vect Y_Vect)
    PerVec (MeCrossProduct CroPro X_Vect)
    )
    (list X_Vect PerVec)
    )
    ;
    ; == Function MeCrossproduct
    ; Calculates the crossproduct of two vectors. The resulting vector
    ; is a vector representing the normal of a plane defined by Ve1 and Ve2.
    ; Arguments [Type]:
    ;   Ve1 = Vector 1 [LIST]
    ;   Ve2 = Vector 2 [LIST]
    ; Return [Type]:
    ;   > Crossproduct of the two vectors [LIST]
    ; Notes:
    ;   None
    ;
    (defun MeCrossproduct (Ve1 Ve2)
    (MeSetZero
    (list
    (- (* (cadr Ve1) (caddr Ve2)) (* (caddr Ve1) (cadr Ve2)))
    (- (* (caddr Ve1) (car Ve2)) (* (car Ve1) (caddr Ve2)))
    (- (* (car Ve1) (cadr Ve2)) (* (cadr Ve1) (car Ve2)))
    )
    )
    )
    Cheers
     
    Jürg Menzi, Aug 11, 2004
    #4
  5. BillZ

    BillZ Guest

    Thanks Robert,
    I poked around for a while in the VB group and though I'm beginning to understand this vector stuff it probably would've only take me a couple of weeks to figure all this out <grn>.


    Bill
     
    BillZ, Aug 11, 2004
    #5
  6. BillZ

    BillZ Guest

    Jürg,

    I stand amazed at how you can just throw this stuff together and have it work so good!

    I will be studying these functions more.
    I have read all about cross products and vectors but I think it would've taken some time before I could've accomplished what you have given me.

    Did I mention it was my birthday? :)

    Many thanks!

    Bill
     
    BillZ, Aug 11, 2004
    #6
  7. BillZ

    Jürg Menzi Guest

    Hi Bill

    Glad to help you...
    Mostly I can grab this stuff from my function libraries.
    Happy birthday!...¦-)

    Cheers
     
    Jürg Menzi, Aug 11, 2004
    #7
  8. BillZ

    BillZ Guest

    Happy birthday!...¦-)<<<

    Thanks,

    Wife's takin me out for dinner! 8^0

    Bill
     
    BillZ, Aug 11, 2004
    #8
  9. BillZ

    Devin Guest

    Bill,

    Happy birthday!!!

    Devin :)
     
    Devin, Aug 12, 2004
    #9
  10. BillZ

    BillZ Guest

    Just a follow up:

    With Jürg's rounding code, I can put the x and y vector at ucs creation time.
    For some reason, I still have to create it at 0,0 origin and move it via put-origin.

    (setq UCS_Tmp (vla-add *ucs_col*
    (vlax-3d-point '(0.0 0.0 0.0))
    (vlax-3d-point x_vec)
    (vlax-3d-point y_vec)
    "TEMP")
    )
    (vla-put-Origin UCS_Tmp bspo)
    (vla-put-ActiveUCS *acaddoc* UCS_Tmp)

    Thanks

    Bill
     
    BillZ, Aug 12, 2004
    #10
  11. BillZ

    Devin Guest

    Bill,

    I could be wrong, but Jürg's code looks like an accurate way to achieve a
    perpendicular vector rather than rounding the vector. And please, correct
    me if I'm wrong, but I think the problem was the same problem that occured
    when you used my matrix functions. If the vectors aren't perpendicular to
    eachother with respect to the origin then bad things could happen. In my
    code it causes the transformations to be off (slightly in your case). In
    autocad's ucs creator code it checks for perpendicularity and denies vectors
    that aren't perpendicular within their required limits.

    And Jürg, thanks for the code, I'll implement it in my own matrix functions!

    Devin
     
    Devin, Aug 12, 2004
    #11
  12. BillZ

    BillZ Guest

    I could be wrong, but Jürg's code looks like an accurate >>>way to achieve a
    Devin,
    I believe rounding is exactly what Jürg's doing with the MeSetZero function.

    I think that problem is the same as what happens with all transformations. The z is slightly off in all cases. I think it's a mathematical limitation with the angles/radians.
    Even the align function does it.


    Yes, this seems to be very "pickey", I think that's why Jürg did the rounding of the elements that were slightly /= to 0.
    Maybe Jürg can shed more light on this...

    Jürg's code does simplify things as I can do the same rotation to 0,0,0 in the WCS simply by setting the UCS, getting the matrix, transposing the matrix and tranforming the triangle object.

    This is what I have so far:

    (setq UCS_Matrx (vla-GetUCSMatrix UCS_Tmp) ;UCS matrix object.
    matrx_list (vlax-safearray->list (variant-value UCS_Matrx)) ;4x4 matrix from UCS.
    perspec_lst (last matrx_list) ;last row of matrix (perspective).
    trans_list (mapcar '- (mapcar '(lambda (x)(cadddr x)) matrx_list)) ;translation part of matrix (made negative).
    trans_list (mapcar '(lambda (a b)(append a (list b))) ;translation part of matrix.
    (list
    (list 1.0 0.0 0.0)
    (list 0.0 1.0 0.0)
    (list 0.0 0.0 1.0))
    trans_list) ;3x4 translation matrix list.
    tran_matrx (append trans_list (list perspec_lst)) ;4x4 translation matrix list.
    3x3_matrx (mapcar '(lambda (x)
    (reverse (cdr (reverse x))))
    (reverse (cdr (reverse matrx_list)))) ;3x3 rotation matrix list.

    3x3_matrx (transpose 3x3_matrx) ;transposed matrix.
    3x4_matrx (mapcar '(lambda (a b)(append a (list b))) 3x3_matrx (list 0 0 0)) ;add zero translation back to list
    4x4_matrx (append 3x4_matrx (list perspec_lst)) ;add fourth row back to matrix.
    Full_matrx (mxm 4x4_matrx tran_matrx) ;multiply rotation by translation.
    New_Matrx (vlax-tmatrix Full_matrx) ;transposed matrix object.
    )

    I'm finding out how much I don't know about translation and how it affects the final placement of the triangle object.

    Bill
     
    BillZ, Aug 12, 2004
    #12
  13. BillZ

    BillZ Guest

    Oh,
    You might want these:

    ;Vladimir Nesterovsky - Transpose Matrix function
    (defun transpose (m)
    (apply 'mapcar (cons 'list m))
    )

    ;;---;
    ;Vladimir Nesterovsky - Multiply Matrix function
    (defun mxm (m q / qt) ;use for matrix multiplication.
    (setq qt (apply 'mapcar (cons 'list q)))
    (mapcar '(lambda (mrow)(mxv qt mrow)) m)
    )
    ;;---;

    Bill
     
    BillZ, Aug 12, 2004
    #13
  14. BillZ

    Jürg Menzi Guest

    Hi Devin

    Welcome...¦-)

    There is finally a precision problem, but it's amazing that the following
    function never had this problem (ok, you can't create an UCS off the xy
    plane):
    Code:
    ;
    ; == Function MeAddUcs
    ; Adds a named UCS to the document.
    ; Arguments [Type]:
    ;   Pnt = UCS origin point [LIST]
    ;   Ang = USC X-angle [REAL]
    ;   Nme = Name [STR]
    ; Return [Type]:
    ;   > UCS object [VLA-OBJECT]
    ;   > False on error
    ; Notes:
    ;   None
    ;
    (defun MeAddUcs (Pnt Ang Nme / UcsObj)
    (if (vl-catch-all-error-p
    (setq UcsObj (vl-catch-all-apply
    'vla-add
    (list
    (vla-get-UserCoordinateSystems
    (vla-get-ActiveDocument
    (vlax-get-acad-object)
    )
    )
    (vlax-3d-point Pnt)
    (vlax-3d-point (polar Pnt Ang 1.0))
    (vlax-3d-point (polar Pnt (+ Ang (/ pi 2)) 1.0))
    Nme
    )
    )
    )
    )
    nil
    UcsObj
    )
    )
    Cheers
     
    Jürg Menzi, Aug 12, 2004
    #14
  15. BillZ

    Devin Guest

    Thanks!
     
    Devin, Aug 12, 2004
    #15
  16. BillZ

    Devin Guest

    Jürg,

    I had read about cross products and a little about what they do. I'm a
    little new to this deep of math. Does your function take a point and
    re-calc that point to a perpendicularity in relation to the origin point?

    Devin
     
    Devin, Aug 12, 2004
    #16
  17. BillZ

    BillZ Guest

    You're welcome,
    And thank you for our interest in this subject.

    Oh, I see there was a couple of other subrs involed in the matrix multiplication.
    Here they are:

    ;Vladimir Nesterovsky - Matrix functions

    (defun dotprod (u v)
    (apply '+ (mapcar '* u v))
    )

    (defun mxv (m v) ;NewP = Matrix * Point
    (mapcar '(lambda (row) (dotprod row v)) m)
    )


    Bill
     
    BillZ, Aug 13, 2004
    #17
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.