- 积分
- 2688
- 明经币
- 个
- 注册时间
- 2006-11-1
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
发表于 2009-4-7 10:27:00
|
显示全部楼层
BIXform.lsp
Block-to-Insert and Insert-to-Block Coordinate Transforms- ;;; A set of routines for transforming back and forth
- ;;; between points found in the block table and points
- ;;; found in block inserts.
- ;;; Jon Fleming (jonf@fleming-group.com)
- ;;; April 16, 1998
- ;;; Copyright (C) 1998 by The Fleming Group
- ;;; Permission to use, copy, modify, and distribute this software
- ;;; for any purpose and without fee is hereby granted, provided
- ;;; that the above copyright notice appears in all copies and
- ;;; that both that copyright notice and the limited warranty and
- ;;; restricted rights notice below appear in all supporting
- ;;; documentation.
- ;;; THE FLEMING GROUP PROVIDES THIS PROGRAM "AS IS" AND WITH ALL
- ;;; FAULTS. THE FLEMING GROUP SPECIFICALLY DISCLAIMS ANY IMPLIED
- ;;; WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.
- ;;; THE FLEMING GROUP DOES NOT WARRANT THAT THE OPERATION OF THE
- ;;; PROGRAM WILL BE UNINTERRUPTED OR ERROR FREE.
- ;;; Usage:
- ;;; The first step is to obtain the Entity Name of
- ;;; an INSERT entity, pass that name to the
- ;;; BlockToInsertSetup function, and save the return
- ;;; value for use in later transformations. Example:
- ;;;
- ;;; (setq InsertEName (car (entsel "\nSelect insert: "))
- ;;; XformSpec (BlockToInsertSetup InsertEName)
- ;;; )
- ;;;
- ;;; The second step is to obtain a point that you wish
- ;;; to transform. This point may be a point obtained
- ;;; from entries in the block table, or a point in the
- ;;; insert entity (expressed in WCS). Example:
- ;;;
- ;;; (setq BlockName (cdr (assoc 2 (entget InsertEName)))
- ;;; BlockEList (tblsearch "BLOCK" BlockName)
- ;;; FirstEntity (entget (cdr (assoc -2 BlockEList)))
- ;;; Point1 (cdr (assoc 10 FirstEntity))
- ;;; )
- ;;;
- ;;; The final step is to transform the point. To transform
- ;;; a point obtained from the block table into the corresponding
- ;;; point in the insert entity, call BlockToInsertXform,
- ;;; passing the point and the return value of BlockToInsertSetup
- ;;; as arguments. The return value will be the corresponding
- ;;; point in the INSERT entity, expressed in WCS. Example:
- ;;;
- ;;; (setq Point2 (BlockToInsertXform Point1 XformSpec))
- ;;;
- ;;; Or, to transform a point (expressed in WCS) obtained from
- ;;; an insert entity into the corresponding point in the
- ;;; block table, use InsertToBlockXform with the same arguments.
- ;;;
- ;;; You may repeat the second and third steps as many times as
- ;;; you wish.
- ;;; NOTE: There are some pathological cases in which the answer
- ;;; is "correct" but not what you want. These routines handle
- ;;; negative and positive scale factors correctly. However, if the
- ;;; scale factors of the insert entity are not equal in magnitude,
- ;;; and the insert has attributes, and the attributes have not been
- ;;; scaled using the same scale factors as the insert entity, and
- ;;; you attempt to transform points such as attribute or attdef
- ;;; insert points, the results will not be what you expect.
- ;;;--------------------------------------------------------------
- ;;; Function to transform a point obtained from a block's
- ;;; specification in the block table into the corresponding
- ;;; point in an insert of that block.
- ;;; Arguments:
- ;;; P1 = A list of three reals defining a point,
- ;;; usually obtained from the block table.
- ;;; TransformSpec = A list of five lists, obtained
- ;;; from the BlockToInsertSetup
- ;;; function.
- ;;; Return value: A list of three reals containing
- ;;; the corresponding point in the INSERT entity,
- ;;; expressed in WCS.
- ;;; NOTE: This function can be fooled in pathological
- ;;; circumstances. If you are transforming a point obtained
- ;;; from an ATTDEF entity in the block table, and the X and/or
- ;;; Y and/or Z scale factors of the block insert have been
- ;;; modified so their magnitudes are not all the same, but
- ;;; the block insert's attributes have not been similarly
- ;;; scaled, the returned point will be where the attribute
- ;;; point "should be" (based on the insert entity's scale
- ;;; factors) rather than where the attribute point _is_.
- ;;; This routine does work correctly with scale factors
- ;;; of different signs.
- (defun BlockToInsertXform (P1 TransformSpec)
- (3dTransformAB
- (nth 0 TransformSpec)
- (nth 1 TransformSpec)
- (nth 2 TransformSpec)
- (nth 3 TransformSpec)
- (nth 4 TransformSpec)
- P1
- ) ;_ end 3dTransformAB
- ) ;_ end defun
- ;;; Function to transform a point obtained from an insert of
- ;;; a block intothe corresponding point in the definition
- ;;; of the block in the block table.
- ;;; Arguments:
- ;;; P1 = A list of three reals defining a point,
- ;;; expressed in WCS.
- ;;; TransformSpec = A list of five lists, obtained
- ;;; from the BlockToInsertSetup
- ;;; function.
- ;;; Return value: A list of three reals containing
- ;;; the corresponding point in the block table,
- ;;; expressed in WCS.
- ;;; NOTE: This function can be fooled in pathological
- ;;; circumstances. If you are transforming a point obtained
- ;;; from an ATTRIBUTE entity in the insert, and the X and/or
- ;;; Y and/or Z scale factors of the block insert have been
- ;;; modified so their magnitudes are not all the same, but
- ;;; the block insert's attributes have not been similarly
- ;;; scaled, the returned point will be where the ATTDEF
- ;;; point in the block table "should be" (based on the
- ;;; insert entity's scale factors) rather than where the
- ;;; ATTDEF point _is_.
- ;;; This routine does work correctly with scale factors
- ;;; of different signs.
- (defun InsertToBlockXform (P1 TransformSpec)
- (3dTransformBA
- (nth 0 TransformSpec)
- (nth 1 TransformSpec)
- (nth 2 TransformSpec)
- (nth 3 TransformSpec)
- (nth 4 TransformSpec)
- P1
- ) ;_ end 3dTransformBA
- ) ;_ end defun
- ;;; Function to set up the transformation specification
- ;;; for transforming coordinates specified in an entry
- ;;; the block table to an insert of that block (or vice
- ;;; versa).
- ;;; Argument: the Entity Name of an INSERT entity
- ;;; To understand the return value, first consider
- ;;; a coordinate system I call the Natural Coordinate
- ;;; System (NCS). The Z axis of the NCS is the same as
- ;;; the Z axis of the insert's Object Coordinate
- ;;; System (OCS). The X Axis of the NCS is rotated
- ;;; (around the OCS Z axis) from the X axis of the OCS
- ;;; by the amount of rotation of the insert. Similarly,
- ;;; the NCS Y axis is rotated (around the OCS Z axis)
- ;;; from the OCS Y axis by the same amount. The origin
- ;;; of the NCS is at the insertion point of the insert.
- ;;; In other words, the NCS is a coordinate system in
- ;;; the block is inserted at (0,0,0) with a rotation
- ;;; angle of zero.
- ;;; Return value: A list of lists containing:
- ;;; 1. A unit vector along the X axis of the
- ;;; insert's NCS, expressed in World
- ;;; Coordinate System (WCS).
- ;;; 2. A unit vector along the Y axis of the
- ;;; insert's NCS, expressed in WCS.
- ;;; 3. A unit vector along the Z axis of the
- ;;; insert's NCS, expressed in WCS.
- ;;; 4. A vector from WCS 0,0,0 to the insert
- ;;; point of the INSERT entity (the origin
- ;;; of the NCS), expressed in WCS.
- ;;; 5. A list of three reals containing the
- ;;; insert's X, Y and Z scale factors.
- (defun BlockToInsertSetup (InsertEname
- /
- InsertEList
- ZAxis
- NCSXAxis
- InsertAngle
- )
- ;; Get the Entity Association List of the insert and the Z
- ;; axis of the NCS (and OCS)
- (setq ZAxis (cdr (assoc 210 (setq InsertEList (entget InsertEName))))
- ;; The OCS X axis is, in OCS, '(1 0 0). The NCS X axis is
- ;; therefore, in OCS,
- ;; ((cos InsertAngle) (sin InsertAngle) 0.0).
- ;; Transforming this vector to WCS gives the NCS X axis in
- ;; WCS:
- InsertAngle (cdr (assoc 50 InsertEList))
- NCSXAxis (trans (list (cos InsertAngle) (sin InsertAngle) 0.0)
- (cdr (assoc 210 InsertEList))
- 0
- ) ;_ end trans
- ) ;_ end setq
- ;; Set up the return value
- (list NCSXAxis
- ;; The Y axis of the NCS (it will be a unit vector
- ;; because it's the cross product of two unit
- ;; vectors at a right angle to each other)
- (VectorCrossProduct ZAxis NCSXAxis)
- ZAxis
- ;; The insertion point of the insert
- (trans (cdr (assoc 10 InsertEList)) ZAxis 0)
- ;; The scale factors
- (list (cdr (assoc 41 InsertEList))
- (cdr (assoc 42 InsertEList))
- (cdr (assoc 43 InsertEList))
- ) ;_ end list
- ) ;_ end list
- ) ;_ end defun
- ;;; Vector cross product function
- ;;; Argument: Two lists, each of three real numbers defining
- ;;; a vector in 3-space
- ;;; Return value: A list of three real numbers containing
- ;;; the first argument crossed with the second argument.
- (defun VectorCrossProduct (InputVector1 InputVector2)
- (list (- (* (cadr InputVector1) (caddr InputVector2))
- (* (cadr InputVector2) (caddr InputVector1))
- ) ;_ end -
- (- (* (caddr InputVector1) (car InputVector2))
- (* (caddr InputVector2) (car InputVector1))
- ) ;_ end -
- (- (* (car InputVector1) (cadr InputVector2))
- (* (car InputVector2) (cadr InputVector1))
- ) ;_ end -
- ) ;_ end list
- ) ;_ end defun
- ;;; Function to carry out an arbitrary 3D coordinate
- ;;; transformation from an "A" coordinate system
- ;;; to a "B" coordinate system. Works between any two
- ;;; Cartesian coordinates of the same handedness, and
- ;;; may work between Cartesian coordinate systems of
- ;;; different handedness (with appropriate negative
- ;;; values in the "SA" argument).
- ;;; The "3DTransformBA" function is the inverse of
- ;;; this function.
- ;;; Arguments:
- ;;; XA = a list of three reals defining a unit vector
- ;;; pointing along the X axis of the "A" coordinate
- ;;; system, expressed in the "B" coordinate system
- ;;; YA = a list of three reals defining a unit vector
- ;;; pointing along the Y axis of the "A" coordinate
- ;;; system, expressed in the "B" coordinate system
- ;;; ZA = a list of three reals defining a unit vector
- ;;; pointing along the Z axis of the "A" coordinate
- ;;; system, expressed in the "B" coordinate system
- ;;; OA = A list of three reals defining a vector from
- ;;; the origin of the "B" coordinate system to the
- ;;; origin of the "A" coordinate system, expressed
- ;;; in the "B" coordinate system
- ;;; SA = A list of three reals defining the scale factors;
- ;;; "B" X axis units per "A" X axis unit, "B" Y axis
- ;;; units per "A" Y axis unit, and "B" Z axis units
- ;;; per "A" Z axis unit
- ;;; P1 = A list of three reals defining a point in the
- ;;; "A" coordinate system
- ;;; Return value: a list of three reals defining the same
- ;;; point as P1, but expressed in the "B" coordinate system
- (defun 3DTransformAB (XA YA ZA OA SA P1 /)
- ;; Scale the input point to "B" system units
- (setq P1 (mapcar '* P1 SA))
- ;; Translate and set up the return value
- (mapcar '+
- OA
- ;; The following does the rotation transformation
- (list (+ (* (car XA) (car P1))
- (* (car YA) (cadr P1))
- (* (car ZA) (caddr P1))
- ) ;_ end +
- (+ (* (cadr XA) (car P1))
- (* (cadr YA) (cadr P1))
- (* (cadr ZA) (caddr P1))
- ) ;_ end +
- (+ (* (caddr XA) (car P1))
- (* (caddr YA) (cadr P1))
- (* (caddr ZA) (caddr P1))
- ) ;_ end +
- ) ;_ end list
- ) ;_ end mapcar
- ) ;_ end defun
- ;;; Function to carry out an arbitrary 3D coordinate
- ;;; transformation from a "B" coordinate system
- ;;; to an "A" coordinate system. Works between any two
- ;;; Cartesian coordinates of the same handedness, and
- ;;; may work between Cartesian coordinate systems of
- ;;; different handedness (with appropriate negative
- ;;; values in the "SA" argument).
- ;;; The "3DTransformAB" function is the inverse of
- ;;; this function.
- ;;; Arguments:
- ;;; XA = a list of three reals defining a unit vector
- ;;; pointing along the X axis of the "A" coordinate
- ;;; system, expressed in the "B" coordinate system
- ;;; YA = a list of three reals defining a unit vector
- ;;; pointing along the Y axis of the "A" coordinate
- ;;; system, expressed in the "B" coordinate system
- ;;; ZA = a list of three reals defining a unit vector
- ;;; pointing along the Z axis of the "A" coordinate
- ;;; system, expressed in the "B" coordinate system
- ;;; OA = A list of three reals defining a vector from
- ;;; the origin of the "B" coordinate system to the
- ;;; origin of the "A" coordinate system, expressed
- ;;; in the "B" coordinate system
- ;;; SA = A list of three reals defining the scale factors;
- ;;; "B" X axis units per "A" X axis unit, "B" Y axis
- ;;; units per "A" Y axis unit, and "B" Z axis units
- ;;; per "A" Z axis unit
- ;;; P1 = A list of three reals defining a point in the
- ;;; "B" coordinate system
- ;;; Return value: a list of three reals defining the same
- ;;; point as P1, but expressed in the "A" coordinate system
- (defun 3DTransformBA (XA YA ZA OA SA P1 /)
- ;; Translate
- (setq P1 (mapcar '- P1 OA))
- ;; Scale and set up the return value
- (mapcar '/
- ;; The following does the rotation
- (list (+ (* (car XA) (car P1))
- (* (cadr XA) (cadr P1))
- (* (caddr XA) (caddr P1))
- ) ;_ end +
- (+ (* (car YA) (car P1))
- (* (cadr YA) (cadr P1))
- (* (caddr YA) (caddr P1))
- ) ;_ end +
- (+ (* (car ZA) (car P1))
- (* (cadr ZA) (cadr P1))
- (* (caddr ZA) (caddr P1))
- ) ;_ end +
- ) ;_ end list
- SA
- ) ;_ end mapcar
- ) ;_ end defun
|
|