Author Topic: Extrusion Direction Based On 3 WCS Points  (Read 3141 times)

0 Members and 1 Guest are viewing this topic.

David Bethel

  • Swamp Rat
  • Posts: 656
Extrusion Direction Based On 3 WCS Points
« on: August 14, 2011, 11:54:14 AM »


I need to calculate a group 210 OCS value based on 3 non-co-linear WCS points
supplied in an exact order:

     Origin_pt     X_Axis_pt    Z-Axis_pt


(defun ocs-3p (opt xpt zpt)

)


I know that I have had this formula a least once in life, but I have hidden from myself.....  I think it was a Steve Johnson snippet

Any ideas?

Thanks!   -David
R12 Dos - A2K

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Extrusion Direction Based On 3 WCS Points
« Reply #1 on: August 14, 2011, 01:03:57 PM »
First thing that comes to mind is to find the orthogonal unit vector using the vector cross product:

Code: [Select]
(defun ocs-3p ( opt xpt zpt / v1 v2 )
  (setq v1 (mapcar '- xpt opt)
        v2 (mapcar '- zpt opt)
  )
  (unit (v^v v1 v2))
)

;; Vector Cross Product - Lee Mac
;; Args: u,v - vectors in R^3

(defun v^v ( u v )
  (list
    (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
    (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
    (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
  )
)

;; Unit Vector - Lee Mac
;; Args: v - vector in R^3

(defun unit ( v )
  ( (lambda ( n )
      (if (not (equal 0.0 n 1e-14))
        (mapcar '(lambda ( x ) (/ x n )) v)
      )
    )
    (distance '(0. 0. 0.) v)
  )
)

But I believe the calculation of the OCS normal vector follows the Arbitrary Axis algorithm which is a little more involved than that.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Extrusion Direction Based On 3 WCS Points
« Reply #2 on: August 14, 2011, 01:18:47 PM »
Translating the Arbitrary Axis Algorithm described here:

Code: [Select]
;; OCS Frame - Lee Mac
;; Uses the Arbitrary Axis Algorithm to define
;; a coordinate frame, given a WCS Unit Normal

(defun LM:OCSFrame ( zvec / xvec )
    (setq xvec
        (unit
            (v^v
                (if
                    (and
                        (< (abs (car  zvec)) 0.015625)
                        (< (abs (cadr zvec)) 0.015625)
                    )
                   '(0.0 1.0 0.0)
                   '(0.0 0.0 1.0)
                )
                zvec
            )
        )
    )
    (list xvec (unit (v^v zvec xvec)) zvec)
)

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Extrusion Direction Based On 3 WCS Points
« Reply #3 on: August 14, 2011, 01:29:59 PM »
Wow. that' a lot of code!  A lot to understand...

I wonder if GeoCal can be used here?

Code: [Select]

nor(p1,p2,p3)

  3D unit normal vector to plane defined by p1, p2, and p3.
  The orientation of the normal is such that the given points go counterclockwise with respect to the normal.

-David
R12 Dos - A2K

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Extrusion Direction Based On 3 WCS Points
« Reply #4 on: August 14, 2011, 01:35:21 PM »
Quote
But I believe the calculation of the OCS normal vector follows the Arbitrary Axis algorithm which is a little more involved than that.

The Arbitrary Axis algorithm is used to construct the OCS 3X3 matrix according to the extrusion direction vector.
The cross product is suffisant to calculate this vector.

To get the OCS matrix, you can use the trans function too :
Code: [Select]
(defun gc:OCSMatrix (zvec)
  (mapcar '(lambda (x) (trans x zvec 0))
  '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  )
)
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Extrusion Direction Based On 3 WCS Points
« Reply #5 on: August 14, 2011, 01:42:54 PM »
Nice shortcut gile - I forgot that the trans function used the Arbitrary Axis Algorithm too :ugly:

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Extrusion Direction Based On 3 WCS Points
« Reply #6 on: August 15, 2011, 08:23:20 AM »
The Arbitrary Axis algorithm is used to construct the OCS 3X3 matrix according to the extrusion direction vector.
The cross product is suffisant to calculate this vector.

To get the OCS matrix, you can use the trans function too :
Code: [Select]
(defun gc:OCSMatrix (zvec)
  (mapcar '(lambda (x) (trans x zvec 0))
  '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  )
)

What is the usage of OCS 3x3 matrix, when if it is used to construct 4x4 transformation matrix, this transformation gives wrong normal Z axis orientation of object...

Code: [Select]
(defun c:OCSMatrix ( / pt1 pt2 zvec tmat obj)
  (vl-load-com)
  (setq pt1 (getpoint "\nPick start point of vector")
pt2 (getpoint pt1 "\nPick end point of vector")
zvec (mapcar '- pt2 pt1)
  )
  (princ "\n")
  (setq tmat (append (mapcar '(lambda (x) (append x '(0.))) (OCSMatrix zvec)) '((0. 0. 0. 1.))))
  (setq obj (vlax-ename->vla-object (car (entsel "\nSelect object you want to transform"))))
  (vla-transformby obj (vlax-tmatrix tmat))
  (princ tmat)
)

(defun OCSMatrix (zvec)
  (mapcar '(lambda (x) (trans x zvec 0))
  '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  )
)
« Last Edit: August 15, 2011, 09:01:31 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Extrusion Direction Based On 3 WCS Points
« Reply #7 on: August 15, 2011, 09:08:40 AM »
I've found mistake... You should use (trans x 0 zvec) :

Code: [Select]
(defun c:OCSMatrix ( / pt1 pt2 zvec tmat obj)
  (vl-load-com)
  (setq pt1 (getpoint "\nPick start point of vector")
pt2 (getpoint pt1 "\nPick end point of vector")
zvec (mapcar '- pt2 pt1)
  )
  (princ "\n")
  (setq tmat (append (mapcar '(lambda (x) (append x '(0.))) (OCSMatrix zvec)) '((0. 0. 0. 1.))))
  (setq obj (vlax-ename->vla-object (car (entsel "\nSelect object you want to transform"))))
  (vla-transformby obj (vlax-tmatrix tmat))
  (princ tmat)
)

(defun OCSMatrix (zvec)
  (mapcar '(lambda (x) (trans x 0 zvec))
  '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  )
)

Now, it works perfect...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Extrusion Direction Based On 3 WCS Points
« Reply #8 on: August 15, 2011, 09:39:15 AM »
Quote
What is the usage of OCS 3x3 matrix
it can be used to define an UCS or with Vladimir Nesterovsky's mxv routine to transform a vector.

Quote
I've found mistake... You should use (trans x 0 zvec)
I don't think so if the task was getting the OCS coordinates.

try:
Code: [Select]
(mxv (gc:ocsmatrix '(1. 2. 3.)) '(10. 20. 0.))and
Code: [Select]
(trans '(10. 20. 0.) 0  '(1. 2. 3.))they retrun the same result.

What you're doing is another task: transform an entity from the WCS to an OCS.
You can do this with a more generic routine:
Code: [Select]
;; gc:TMatrixFromTo
;; Returns the 4x4 transformation matrix form a coordinate system
;; to another one.
;;
;; Arguments
;; from an to: the same arguments as for the trans function.

(defun gc:TMatrixFromTo (from to)
  (append
    (mapcar
      (function
(lambda (v o)
  (append (trans v from to T) (list o))
)
      )
      (list '(1. 0. 0.) '(0. 1. 0.) '(0. 0. 1.))
      (trans '(0. 0. 0.) to from)
    )
    (list '(0. 0. 0. 1.))
  )
)

Using: (vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo 0 zvec)))
Speaking English as a French Frog

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Extrusion Direction Based On 3 WCS Points
« Reply #9 on: August 15, 2011, 10:33:42 AM »
Can I use :
Code: [Select]
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo zvec1 zvec2)))
directly, or I must do it over WCS...
Code: [Select]
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo zvec1 0)))
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo 0 zvec2)))
:???:
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Extrusion Direction Based On 3 WCS Points
« Reply #10 on: August 15, 2011, 11:39:34 AM »
Not exactly,

(gc:TMatrixFromTo zvec1 zvec2) is equal to:
(mxm (gc:TMatrixFromTo v1 0) (gc:TMatrixFromTo 0 v2))
where mxm Vladimir Nesterovsky's multiply/combinates two matrices.
The matrix multiplication is not commutative. If we look at a matrix multiplication as the composition of linear transformations we have to consider the transformations order: the first transformation is described by the right hand in the multiplication, the second one, by the left hand.
So,
Code: [Select]
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo zvec1 zvec2)))is eqivalent to:
Code: [Select]
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo 0 zvec2)))
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo zvec1 0)))
Speaking English as a French Frog

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Extrusion Direction Based On 3 WCS Points
« Reply #11 on: August 15, 2011, 12:09:11 PM »
I guess align command works based on :
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo zvec1 zvec2)))

so this is all sufficient in terms of usage in CAD entities manipulations...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Extrusion Direction Based On 3 WCS Points
« Reply #12 on: August 15, 2011, 04:08:58 PM »
Yes, gile you're wright... This is what works :

Code: [Select]
;; TRP
;; Transposes a matrix -Doug Wilson-
;;
;; Argument : a matrix

(defun trp (m) (apply 'mapcar (cons 'list m)))

;; MXV
;; Applies a transformation matrix to a vector -Vladimir Nesterovsky-
;;
;; Arguments : a matrix and a vector

(defun mxv (m v)
  (mapcar (function (lambda (r) (apply '+ (mapcar '* r v)))) m)
)

;; MXM
;; Multiplies (combinates) two matrices -Vladimir Nesterovsky-
;;
;; Arguments : two matrices

(defun mxm (m q)
  (mapcar (function (lambda (r) (mxv (trp q) r))) m)
)

;; gc:TMatrixFromTo
;; Returns the 4x4 transformation matrix form a coordinate system
;; to another one.
;;
;; Arguments
;; from an to: the same arguments as for the trans function.

(defun gc:TMatrixFromTo (from to)
  (append
    (mapcar
      (function
(lambda (v o)
  (append (trans v from to T) (list o))
)
      )
      (list '(1. 0. 0.) '(0. 1. 0.) '(0. 0. 1.))
      (trans '(0. 0. 0.) to from)
    )
    (list '(0. 0. 0. 1.))
  )
)

(defun c:OCS-OCSMatrix1 ( / pt1 pt2 zvec1 pt3 pt4 zvec2 tmat obj)
  (vl-load-com)
  (setq pt1 (getpoint "\nPick start point of first normal vector : ")
pt2 (getpoint pt1 "\nPick end point of first normal vector : ")
zvec1 (mapcar '- pt2 pt1)
        pt3 (getpoint "\nPick start point of second normal vector : ")
pt4 (getpoint pt1 "\nPick end point of second normal vector : ")
zvec2 (mapcar '- pt4 pt3)
  )
  (setq obj (vlax-ename->vla-object (car (entsel "\nSelect object you want to transform"))))
  (setq tmat (mxm (gc:TMatrixFromTo zvec1 0) (gc:TMatrixFromTo 0 zvec2)))
  (vla-transformby obj (vlax-tmatrix tmat))
  (princ "\n")
  (princ tmat)
(princ)
)

(defun c:OCS-OCSMatrix2 ( / pt1 pt2 zvec1 pt3 pt4 zvec2 obj)
  (vl-load-com)
  (setq pt1 (getpoint "\nPick start point of first normal vector : ")
pt2 (getpoint pt1 "\nPick end point of first normal vector : ")
zvec1 (mapcar '- pt2 pt1)
        pt3 (getpoint "\nPick start point of second normal vector : ")
pt4 (getpoint pt1 "\nPick end point of second normal vector : ")
zvec2 (mapcar '- pt4 pt3)
  )
  (setq obj (vlax-ename->vla-object (car (entsel "\nSelect object you want to transform"))))
  (vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo 0 zvec2)))
  (vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo zvec1 0)))
(princ)
)

(defun c:OCS-OCSMatrix3 ( / pt1 pt2 zvec1 pt3 pt4 zvec2 obj)
  (vl-load-com)
  (setq pt1 (getpoint "\nPick start point of first normal vector : ")
pt2 (getpoint pt1 "\nPick end point of first normal vector : ")
zvec1 (mapcar '- pt2 pt1)
        pt3 (getpoint "\nPick start point of second normal vector : ")
pt4 (getpoint pt1 "\nPick end point of second normal vector : ")
zvec2 (mapcar '- pt4 pt3)
  )
  (setq obj (vlax-ename->vla-object (car (entsel "\nSelect object you want to transform"))))
  (vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo zvec1 0)))
  (vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo 0 zvec2)))
(princ)
)

And as you said OCS-OCSMatrix1 = OCS-OCSMatrix2...

Quote
But also OCS-OCSMatrix2 = OCS-OCSMatrix3, and therefore OCS-OCSMatrix1 = OCS-OCSMatrix3... :-o
« Last Edit: August 16, 2011, 07:44:45 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: Extrusion Direction Based On 3 WCS Points
« Reply #13 on: August 16, 2011, 09:04:15 AM »
Quote
But also OCS-OCSMatrix2 = OCS-OCSMatrix3, and therefore OCS-OCSMatrix1 = OCS-OCSMatrix3... :-o
Strange, maybe I did something wrong while inspecting OCS-OCSMatrixes...

But here what you mentioned about mxm had sense :
http://www.theswamp.org/index.php?topic=34886.new#new

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube