3D distance and angle.

Discussion in 'AutoCAD' started by BillZ, Jun 9, 2004.

  1. BillZ

    Devin Guest

    Bill,

    the 3pxa_matrix function takes the arguments as follows:

    (3pxa_matrix <origin point> <x direction vector> <y direction vector>
    <additional rotation about x axis in degrees (zero if none)>)

    assuming:
    delta triangle on a plane with points a1 b1 c1.
    main triangle on a plane (the same as delta triangle or other) with points
    a2 b2 c2.
    co-linear pts between delta triangle and main triangle are a1=a2 b1=b2.

    now the first step is to create a matrix aligned with the delta triangle.
    This is the triangle you wish to change.

    syntax (line 1):
    (3pxa_matrix a1 b1 c1 180)

    notice that I flipped the matrix by 180 degrees about the x axis. This is
    so that when we create the final matrix it will be facing the same direction
    as the first and not inverted on the opposite direction. Draw it out on
    paper, examine it and I'm sure you'll see why.

    the next step is to transform the delta triangle's points thru the newly
    created matrix (doorway). This puts the points at 0,0,0 and oriented with
    the WCS.

    syntax (line 2):
    (setq
    a1 (mtrans a1 0 1)
    b1 (mtrans b1 0 1)
    c1 (mtrans c1 0 1)
    )

    now it's time to set up the final matrix or doorway to our final position.
    And that's simply creating a matrix along the alignment edge of the
    triangles flat with the base triangle, since the base triangle is our
    destination plane...

    syntax (line 3):
    (3pxa_matrix a2 b2 c2 0.0)

    notice that I didn't flip this matrix about the x axis 180 degrees this
    time. It only needs to be done once, and on either matrix, since both
    matrix's would actually face each other had we not flipped one of them. If
    we didn't flip one or the other it would mirror the delta triangle if I'm
    not incorrect.

    summary so far:
    The first matrix (line 1) created a doorway for the delta triangles points
    to a holding frame that is aligned with the WCS at 0,0,0 as the base. The
    second matrix (line 3) created a doorway to transport those temporary points
    in the holding frame to the matrix that's aligned with the plane of the base
    triangle. That's the final destination of the points.

    Now we transform the points thru the new doorway...

    syntax (line 4):
    (setq
    a1 (mtrans a1 1 0)
    b1 (mtrans b1 1 0)
    c1 (mtrans c1 1 0)
    )

    to understand a little about the mtrans function, what it does is this.
    (mtrans pt 0 1) means to transform pt from 0 (WCS) to 1 (matrix). (mtrans
    pt 1 0) means to transform pt from 1 (matrix) to 0 (WCS). And I guess I'm
    pretty sure you already knew that, but for anyone else that's reading.

    So really, in concept all that we are doing is creating two doors to
    transform the points from one place and orientation to another place and
    orientation. And to do that, we need a start door (line 1) and an end door
    (line 3) and we need to step thru the doors (lines 2 & 4).

    Like dimensional doorways from one location and orientation in space to
    another. Stargate? :)

    I hope this helps, let me know and if it doesn't then I'll test a working
    example and post that too.

    Devin
     
    Devin, Jun 14, 2004
    #21
  2. BillZ

    BillZ Guest

    Devin,
    I was picking the triangles in the wrong order.

    This works if I draw a new triangle with points returned by the mtrans function. But if I use (vla-transformby rec_1 ucs_matrix_array) it flings the triangle off in space.
    There may be another step I need to do?

    Thanks

    Bill
     
    BillZ, Jun 14, 2004
    #22
  3. BillZ

    Devin Guest

    BillZ,

    In order to use the transformby function you have to create an inverse
    matrix. Notice that the mtrans and trans functions have two arguments that
    specify from and to (ie: (mtrans pt 0 1) & (mtrans pt 1 0)) this allows
    either passing the pt thru the matrix or the inverse matrix. Also notice
    that the transformby function doesn't allow these arguments. What we'll
    have to do is establish two functions for (3pxa_matrix), one that creates a
    matrix and the other that creates an inverse matrix.

    let me work on it a bit and I'll come up with something soon.

    Devin
     
    Devin, Jun 15, 2004
    #23
  4. BillZ

    Devin Guest

    Bill,

    I went ahead and added the inverse matrix switch to the 3pxa_matrix
    function, the inverse matrix is nothing more than the transposition of the
    3x3 rotation matrix portion of the transformation matrix. Simply add any
    value other than nil to the <inverse> argument to create an inverse matrix.
    I don't know which matrix in your sequence would be the inverse. Either the
    first or the second (guess you've got a 50/50 chance of getting it right the
    first time :), try and let me know.

    (defun 3pxa_matrix ( origin xvector yvector xangle inverse
    /
    -x org -y -z xo yo zo xx yx zx xy yy zy xz yz zz numx
    numy numz v a
    )
    (setq
    ;create new axis
    xangle (dtor (sign xangle))
    v (mapcar;magnify vector a factor of 100
    '(lambda (a)
    (* a 100.0)
    )
    (vector origin xvector)
    )
    yvector (vector_translate yvector v)
    -y (axial_rotate yvector 180d origin xvector)
    -x (axial_rotate origin 180d yvector -y)
    org (midpoint yvector -y)
    -y (axial_rotate -y xangle origin xvector)
    -z (axial_rotate -y 90d origin xvector)
    )
    (setq
    xo (car org)
    yo (cadr org)
    zo (caddr org)
    xx (car -x)
    yx (cadr -x)
    zx (caddr -x)
    xy (car -y)
    yy (cadr -y)
    zy (caddr -y)
    xz (car -z)
    yz (cadr -z)
    zz (caddr -z)
    numx (sqrt (+ (sqr (- xx xo)) (sqr (- yx yo)) (sqr (- zx zo))))
    numy (sqrt (+ (sqr (- xy xo)) (sqr (- yy yo)) (sqr (- zy zo))))
    numz (sqrt (+ (sqr (- xz xo)) (sqr (- yz yo)) (sqr (- zz zo))))
    v (vector (list 0.0 0.0 0.0) origin)
    )
    (if
    inverse
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- yx yo) numx) (/ (- zx zo) numx) (car
    v))
    (list (/ (- xy xo) numy) (/ (- yy yo) numy) (/ (- zy zo) numy)
    (cadr v))
    (list (/ (- xz xo) numz) (/ (- yz yo) numz) (/ (- zz zo) numz)
    (caddr v))
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- xy xo) numy) (/ (- xz xo) numz) (car
    v))
    (list (/ (- yx yo) numx) (/ (- yy yo) numy) (/ (- yz yo) numz)
    (cadr v))
    (list (/ (- zx zo) numx) (/ (- zy zo) numy) (/ (- zz zo) numz)
    (caddr v))
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    )
    ucs_matrix
    )
     
    Devin, Jun 15, 2004
    #24
  5. BillZ

    Devin Guest

    Oops forgot to inverse the translation matrix portion of the transformation
    matrix. Here ya go, I'm going to run a test myself to make sure it works
    for you. Don't use the inverse matrix switch with mtrans as it will give
    unexpected results...

    (defun 3pxa_matrix ( origin xvector yvector xangle inverse
    /
    -x org -y -z xo yo zo xx yx zx xy yy zy xz yz zz numx
    numy numz v a
    )
    (setq
    ;create new axis
    xangle (dtor (sign xangle))
    v (mapcar;magnify vector a factor of 100
    '(lambda (a)
    (* a 100.0)
    )
    (vector origin xvector)
    )
    yvector (vector_translate yvector v)
    -y (axial_rotate yvector 180d origin xvector)
    -x (axial_rotate origin 180d yvector -y)
    org (midpoint yvector -y)
    -y (axial_rotate -y xangle origin xvector)
    -z (axial_rotate -y 90d origin xvector)
    )
    (setq
    xo (car org)
    yo (cadr org)
    zo (caddr org)
    xx (car -x)
    yx (cadr -x)
    zx (caddr -x)
    xy (car -y)
    yy (cadr -y)
    zy (caddr -y)
    xz (car -z)
    yz (cadr -z)
    zz (caddr -z)
    numx (sqrt (+ (sqr (- xx xo)) (sqr (- yx yo)) (sqr (- zx zo))))
    numy (sqrt (+ (sqr (- xy xo)) (sqr (- yy yo)) (sqr (- zy zo))))
    numz (sqrt (+ (sqr (- xz xo)) (sqr (- yz yo)) (sqr (- zz zo))))
    v (vector (list 0.0 0.0 0.0) origin)
    )
    (if
    inverse
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- yx yo) numx) (/ (- zx zo) numx)
    (sign (car v)))
    (list (/ (- xy xo) numy) (/ (- yy yo) numy) (/ (- zy zo) numy)
    (sign (cadr v)))
    (list (/ (- xz xo) numz) (/ (- yz yo) numz) (/ (- zz zo) numz)
    (sign (caddr v)))
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- xy xo) numy) (/ (- xz xo) numz) (car
    v))
    (list (/ (- yx yo) numx) (/ (- yy yo) numy) (/ (- yz yo) numz)
    (cadr v))
    (list (/ (- zx zo) numx) (/ (- zy zo) numy) (/ (- zz zo) numz)
    (caddr v))
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    )
    ucs_matrix
    )
     
    Devin, Jun 15, 2004
    #25
  6. BillZ

    BillZ Guest

    No problem,
    I'll be working on this thing, in varying capacities, right along.
    I find this subject quite interesting.

    thanks for the help.

    Bill
     
    BillZ, Jun 15, 2004
    #26
  7. BillZ

    Devin Guest

    BillZ,

    Looking back (when I researched matrices and transforming them) I remember
    that the process of applying the translation vector to the point your
    transforming was different depending on which way you were going (ie:
    ucs->wcs or wcs->ucs). The transformby function only applies it in one
    direction, so the inverse matrix may need to be defined differently. Let me
    look into it some more and I'll see what I can come up with.

    Devin
     
    Devin, Jun 15, 2004
    #27
  8. BillZ

    Devin Guest

    BillZ,

    I fixed it, you have to trick the program by moving the object from the
    origin pt to 0,0,0 then perform the inverse transformby then perform the
    normal transformby. Look at the sequence of the delta command, also I
    changed the 3pxa_matrix function a little...

    (defun c:delta ( / obj ent )
    (setq obj (vlax-ename->vla-object (setq ent (car (entsel "\nSelect object
    to transform: ")))))
    (princ "\nSelect common edge...")
    (setq morig (getpoint "\nSelect origin point: "))
    (setq mxv (getpoint morig "\nSelect xvector direction: "))
    (princ "\nDelta triangle plane...")
    (setq myv (getpoint morig "\nSelect yvector direction: "))
    (princ "\nBase triangle plane...")
    (setq nyv (getpoint morig "\nSelect yvector direction: "))
    (3pxa_matrix morig mxv myv 180.0 t)
    (vla-move obj (vlax-3d-point morig) (vlax-3d-point (list 0 0 0)))
    (vla-transformby obj ucs_matrix_array)
    (3pxa_matrix morig mxv nyv 0.0 nil)
    (vla-transformby obj ucs_matrix_array)
    )

    (defun 3pxa_matrix ( origin xvector yvector xangle inverse
    /
    -x org -y -z xo yo zo xx yx zx xy yy zy xz yz zz numx
    numy numz v a
    )
    (setq
    ;create new axis
    xangle (dtor (sign xangle))
    v (mapcar;magnify vector a factor of 100
    '(lambda (a)
    (* a 100.0)
    )
    (vector origin xvector)
    )
    yvector (vector_translate yvector v)
    -y (axial_rotate yvector 180d origin xvector)
    -x (axial_rotate origin 180d yvector -y)
    org (midpoint yvector -y)
    -y (axial_rotate -y xangle origin xvector)
    -z (axial_rotate -y 90d origin xvector)
    )
    (setq
    xo (car org)
    yo (cadr org)
    zo (caddr org)
    xx (car -x)
    yx (cadr -x)
    zx (caddr -x)
    xy (car -y)
    yy (cadr -y)
    zy (caddr -y)
    xz (car -z)
    yz (cadr -z)
    zz (caddr -z)
    numx (sqrt (+ (sqr (- xx xo)) (sqr (- yx yo)) (sqr (- zx zo))))
    numy (sqrt (+ (sqr (- xy xo)) (sqr (- yy yo)) (sqr (- zy zo))))
    numz (sqrt (+ (sqr (- xz xo)) (sqr (- yz yo)) (sqr (- zz zo))))
    )
    (if
    inverse
    (setq v (vector origin (list 0.0 0.0 0.0)))
    (setq v (vector (list 0.0 0.0 0.0) origin))
    )
    (if
    inverse
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- yx yo) numx) (/ (- zx zo) numx) 0.0)
    (list (/ (- xy xo) numy) (/ (- yy yo) numy) (/ (- zy zo) numy) 0.0)
    (list (/ (- xz xo) numz) (/ (- yz yo) numz) (/ (- zz zo) numz) 0.0)
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- xy xo) numy) (/ (- xz xo) numz) (car
    v))
    (list (/ (- yx yo) numx) (/ (- yy yo) numy) (/ (- yz yo) numz)
    (cadr v))
    (list (/ (- zx zo) numx) (/ (- zy zo) numy) (/ (- zz zo) numz)
    (caddr v))
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    )
    ucs_matrix
    )
     
    Devin, Jun 15, 2004
    #28
  9. BillZ

    BillZ Guest

    Devin,
    Worked good first time! :)
    I'm ready to leave for vacation and have another project to do when I get back so I'll have to test it more when I get back.
    It should be a good start for what I wanted.

    Thanks Again!

    Bill
     
    BillZ, Jun 15, 2004
    #29
  10. BillZ

    Devin Guest

    Bill,

    use the following modified functions...

    (defun c:delta ( / obj ent )
    (setq obj (vlax-ename->vla-object (setq ent (car (entsel "\nSelect object
    to transform: ")))))
    (princ "\nSelect common edge...")
    (setq morig (getpoint "\nSelect origin point: "))
    (setq mxv (getpoint morig "\nSelect xvector direction: "))
    (princ "\nDelta triangle plane...")
    (setq myv (getpoint morig "\nSelect yvector direction: "))
    (princ "\nBase triangle plane...")
    (setq nyv (getpoint morig "\nSelect yvector direction: "))
    (3pxa_matrix morig mxv myv 180.0 t)
    (vla-move obj (vlax-3d-point morig) (vlax-3d-point (list 0 0 0)))
    (vla-transformby obj ucs_matrix_array)
    (3pxa_matrix morig mxv nyv 0.0 nil)
    (vla-transformby obj ucs_matrix_array)
    )

    (defun 3pxa_matrix ( origin xvector yvector xangle inverse
    /
    -x org -y -z xo yo zo xx yx zx xy yy zy xz yz zz numx
    numy numz v a
    )
    (setq
    ;create new axis
    xangle (dtor (sign xangle))
    v (mapcar;magnify vector a factor of 100
    '(lambda (a)
    (* a 100.0)
    )
    (vector origin xvector)
    )
    yvector (vector_translate yvector v)
    -y (axial_rotate yvector 180d origin xvector)
    -x (axial_rotate origin 180d yvector -y)
    org (midpoint yvector -y)
    -y (axial_rotate -y xangle origin xvector)
    -z (axial_rotate -y 90d origin xvector)
    )
    (setq
    xo (car org)
    yo (cadr org)
    zo (caddr org)
    xx (car -x)
    yx (cadr -x)
    zx (caddr -x)
    xy (car -y)
    yy (cadr -y)
    zy (caddr -y)
    xz (car -z)
    yz (cadr -z)
    zz (caddr -z)
    numx (sqrt (+ (sqr (- xx xo)) (sqr (- yx yo)) (sqr (- zx zo))))
    numy (sqrt (+ (sqr (- xy xo)) (sqr (- yy yo)) (sqr (- zy zo))))
    numz (sqrt (+ (sqr (- xz xo)) (sqr (- yz yo)) (sqr (- zz zo))))
    )
    (if
    inverse
    (setq v (vector origin (list 0.0 0.0 0.0)))
    (setq v (vector (list 0.0 0.0 0.0) origin))
    )
    (if
    inverse
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- yx yo) numx) (/ (- zx zo) numx) 0.0)
    (list (/ (- xy xo) numy) (/ (- yy yo) numy) (/ (- zy zo) numy) 0.0)
    (list (/ (- xz xo) numz) (/ (- yz yo) numz) (/ (- zz zo) numz) 0.0)
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    (setq
    ucs_matrix
    (list
    (list (/ (- xx xo) numx) (/ (- xy xo) numy) (/ (- xz xo) numz) (car
    v))
    (list (/ (- yx yo) numx) (/ (- yy yo) numy) (/ (- yz yo) numz)
    (cadr v))
    (list (/ (- zx zo) numx) (/ (- zy zo) numy) (/ (- zz zo) numz)
    (caddr v))
    (list 0.0 0.0 0.0 1.0)
    )
    ucs_matrix_array (vlax-tmatrix ucs_matrix)
    )
    )
    ucs_matrix
    )
     
    Devin, Jun 15, 2004
    #30
  11. BillZ

    Devin Guest

    oh, and have fun on your vacation :)
     
    Devin, Jun 15, 2004
    #31
  12. BillZ

    BillZ Guest

    Better yet.
    Thanks.

    Bill
     
    BillZ, Jun 15, 2004
    #32
  13. BillZ

    Devin Guest

    Bill,

    I thought maybe I should expand a little on what I did to make it work...

    A transformation from a 4x4 transformation matrix is done by first
    multiplying the 3x3 matrix by the point to be transformed and after that
    applying the translation vector at the far right of the 4x4 matrix to the
    point. That's the steps to transforming to a matrix. To transform from a
    matrix you must first subtract the translation vector and after that
    multiply the pt to be transformed by the transposition of the 3x3 rotation
    matrix. To understand a transposition of a 3x3 matrix look at the
    following:

    simple 3x3 matrix...

    1 2 3
    4 5 6
    7 8 9

    and that same matrix transposed...

    1 4 7
    2 5 8
    3 6 9

    As you can see the transposition is simply the matrix mirrored along a line
    from the top left to the bottom right of the matrix. The interesting
    property of the transposition is that when you multiply a vector by the
    transposition matrix it actual reverses the rotation.

    HTH,

    Devin
     
    Devin, Jun 16, 2004
    #33
  14. BillZ

    BillZ Guest

    Very interesting.
    I will look at this more closely as time permits.

    Thanks

    Bill
     
    BillZ, Jun 22, 2004
    #34
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.