- UID
- 151438
- 积分
- 440
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2004-6-21
- 最后登录
- 1970-1-1
|
发表于 2004-9-12 10:20:08
|
显示全部楼层
建立一个空块,blkname为块名,ip为插入点
(defun AddEmpBlock (blkname ip)
(setq blocks (vla-get-blocks (vla-get-activeDocument (vlax-get-acad-object))))
(vla-add blocks (vlax-3d-point ip) blkname)
)
如何得到用多义线剪裁过的光栅图象的各个角点坐标?
(defun c:GetImgVerLst()
(setq en (car (entsel "\n选择image: ")))
(setq el (entget en))
(foreach sublst el
(if (= (car sublst) 14)
(setq ImgVerLst (cons (cdr sublst) ImgVerLst))))
(command "pline")
(foreach vertex ImgVerLst
(command vertex))
(command "")
)
上面程序可以生成OCS下该image的边界pline线
再从image object得到:
(vla-get-origin imgObj) --->原点
(/ (vla-get-scalefactor imgObj) (vla-get-width imgObj)) ---->比例
(vla-get-rotation imgObj) ---->旋转角度
通过以上三个参量可以构建转换矩阵,最后用transformby方法把刚才
生成的OCS下的图像边界plines线变换到实际的位置。
这是比较笨拙的方法,但绝对可行。
或许还有更简单直接的方法,这里仅供大家讨论。
Sorry, 发贴之后才看到长老的跟贴。但(trans p14 objname 0)的方法好像行不通。可能是因为image对象上的坐标系不是一般的OCS.
终于在网上找了Jon Fleming的解答,应该和我的想法差不多。
用法:(ImageClippingBoundary (car (entsel "\选择image:")))
[php]
;;; Function to convert a 2D vector to 3D by adding a Z coordinate
;;; of zero
;;; Argument: A list of two or more real numbers
;;; Return value: The first two items of the list with 0.0 appended
(defun 2DVectorTo3DVector (InputVector)
(list (car InputVector) (cadr InputVector) 0.0)
) ;_ end defun
;;; Function to find the magnitude of a vector.
;;; Argument: A list N of real numbers defining an
;;; N-dimensional vector
;;; Return value: A positive real number giving the
;;; magnitude of the vector
(defun VectorMagnitude (InputVector)
(sqrt (apply '+ (mapcar '(lambda (x) (* x x)) InputVector)))
) ;_ end defun
;;; Function to normalize a vector
;;; Argument: A list of N real numbers defining an
;;; N-dimensional vector. The magnitude of this vector
;;; must NOT be zero!
;;; Return value: A list of N real numbers defining an
;;; N dimensional vector with unit magnitude that points
;;; in the same direction as the input vector
(defun NormalizeVector (InputVector / Magnitude)
(setq Magnitude (VectorMagnitude InputVector))
(mapcar '(lambda (x) (/ x Magnitude)) InputVector)
) ;_ 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 between an "A" coordinate system
;;; and a "B" coordinate system. The two coordinate
;;; systems must both be right handed Cartesian systems.
;;; 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 3DTransform (XA YA ZA OA SA P1 /)
;; Scale the input point to "B" system units
(setq P1 (mapcar '* P1 SA)
;; Rotate into the "B" coordinate system
P1 (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
;; Translate
P1 (mapcar '+ P1 OA)
) ;_ end setq
) ;_ end defun
;;; Subject: Re: OCS (IMAGE entity) to WCS, last time or I give up?
;;; Date: Thu, 09 Apr 1998 20:03:59 EDT
;;; From: Jon Fleming <jonf@fleming-group.com>
;;; Organization: The Fleming Group
;;; Newsgroups: autodesk.autocad.customization
;;; OK, I think I've got it now ...
;;; There are actually two coordinate systems associated with an IMAGE entity.
;;; One, which I'll call Image Coordinate System (ICS) has an origin at the
;;; lower left corner of a box which just encloses the image (the insertion
;;; point contained in the 10 group). The X and Y axes of the ICS are given (in
;;; WCS) by the 11 and 12 groups. The units of the ICS axes are arbitrary,
;;; since AutoCAD doesn't specify any points or vectors in ICS.
;;; The other, which I'll call Pixel Coordinate System (PCS) has an origin
;;; one-half pixel below and to the right of the upper left corner of a box
;;; which just encloses the image (and with the box sides parallel to the ICS X
;;; and Y axes). The PCS X axis is parallel to the ICS X axis, and points in
;;; the same direction as the ICS X axis. The PCS Y axis is parallel to the ICS
;;; Y axis, but it points in the _opposite_ direction as the ICS Y axis. The
;;; axis units of the PCS are pixels, and need not be the same size in the X
;;; direction and the Y direction.
;;; Neither PCS nor ICS are an OCS.
;;; PCS or ICS or both could be left-handed, but it's impossible to tell, since
;;; AutoCAD never gives us any non-zero Z values in PCS or ICS. There's no
;;; error in treating both as right-handed.
;;; Here's a new version of the (ImageClippingBoundary ...) function; all the
;;; other functions I posted yesterday need no change.
;;; jrf
;;; Function to find the clipping boundary of an AutoCAD R14 IMAGE
;;; object.
;;; Argument: the Entity name of an Image object.
;;; Return value: a list of 3D points, in WCS, at the corners
;;; of the clipping boundary.
(defun ImageClippingBoundary (ImageEName / ImageEList CornerList
ICSXInWCS ICSYInWCS ICSZInWCS
UnitsPerPixelScaleVector ImageInsert
LLCorner URCorner LRCorner ULCorner
CurrentCorner YMax
)
;; There are two coordinate systems involved in an IMAGE entity.
;; And neither of them is an Object Coordinate System.
;; One system I will call Image Coordinate System (ICS). The
;; origin of the ICS is at the point specified (in WCS) in the
;; 10 group, and is at the lower left extents of the image.
;; The direction of the ICS X axis is given by the
;; vector (expressed in WCS) in the 11 group, and the direction
;; of the ICS Y axis is given by the vector (expressed in WCS)
;; in the 12 group. The units of the ICS are arbitrary, because
;; no points are ever specified in ICS. I will choose pixels
;; as the ICS units. Pixels need not be the same in the ICS
;; X and Y directions.
;; The other system I will call Pixel Coordinate System (PCS).
;; The PCS origin is one-half pixel to the right of the
;; leftmost point of the image and one-half pixel below the
;; uppermost point of the image. The PCS X axis is parallel to
;; and in the same direction as the ICS X axis. The PCS Y axis
;; is parallel to but pointing in the opposite direction from the
;; ICS Y axis (positive towards the botom of the image). The units
;; of the PCS are pixels, which may not be the same in the PCS
;; X and Y directions.
;; The clipping boundary coordinates (41 groups) are expressd in
;; PCS.
;; Either the ICS or the PCS, or both, may be left-handed. It is
;; impossible to tell, because no Z values are ever given in either
;; system.
(setq ImageEList
(entget ImageEname)
;; Get a vector along the X axis of the ICS,
;; specified in WCS
ICSXInWCS
(cdr (assoc 11 ImageEList))
;; And a vector along the Y axis of the ICS
ICSYInWCS
(cdr (assoc 12 ImageEList))
;; Get the size of a pixel along the ICS X, Y, and Z axes
;; in drawing units
UnitsPerPixelScaleVector
(list (VectorMagnitude ICSXInWCS)
(VectorMagnitude ICSYInWCS)
1.0
) ;_ end list
;; Scale the two vectors to unit magnitude
ICSXInWCS
(NormalizeVector ICSXInWCS)
ICSYInWCS (NormalizeVector ICSYInWCS)
;; Get a vector of unit magnitude along the
;; ICS Z axis, specified in WCS (assuming
;; a right-handed ICS)
ICSZInWCS
(VectorCrossProduct ICSXInWCS ICSYInWCS)
;; Get the image's insert point in WCS
ImageInsert
(cdr (assoc 10 ImageEList))
;; Get the Y extent of the image in pixels,
;; needed to convert PCS to ICS
Ymax
(caddr (assoc 13 IMageEList))
) ;_ end setq
;; If the clipping boundary is rectangular ...
(if (= 1 (cdr (assoc 71 ImageEList)))
(progn
(setq
;; Isolate the two 14 groups
ImageEList (member (assoc 14 ImageEList) ImageEList)
;; Get the lower left corner in PCS
ULCorner (2DVectorTo3DVector (cdr (nth 0 ImageElist)))
;; Convert to ICS
ULCorner (list (+ 0.5 (car ULCorner))
(- YMax (cadr ULCorner) 0.5)
0.0
) ;_ end list
;; And the upper right corner in PCS
LRCorner (2DVectorTo3DVector (cdr (nth 1 ImageElist)))
;; Convert to ICS
LRCorner (list (+ 0.5 (car LRCorner))
(- YMax (cadr LRCorner) 0.5)
0.0
) ;_ end list
;; And the lower right and upper left corners in ICS
URCorner (list (car LRCorner) (cadr ULCorner) 0.0)
LLCorner (list (car ULCorner) (cadr LRCorner) 0.0)
;; And construct the return list
CornerList (list
(3DTransform
ICSXInWCS
ICSYInWCS
ICSZInWCS
ImageInsert
UnitsPerPixelScaleVector
LLCorner
) ;_ end 3DTransform
(3DTransform
ICSXInWCS
ICSYInWCS
ICSZInWCS
ImageInsert
UnitsPerPixelScaleVector
LRCorner
) ;_ end 3DTransform
(3DTransform
ICSXInWCS
ICSYInWCS
ICSZInWCS
ImageInsert
UnitsPerPixelScaleVector
URCorner
) ;_ end 3DTransform
(3DTransform
ICSXInWCS
ICSYInWCS
ICSZInWCS
ImageInsert
UnitsPerPixelScaleVector
ULCorner
) ;_ end 3DTransform
) ;_ end list
) ;_ end setq
) ;_ end progn
;; The clipping boundary is polygonal
(progn
;; Isolate the 14 groups
(setq ImageEList (member (assoc 14 ImageEList) ImageEList))
;; Loop over corners
(foreach DXFPair ImageEList
;; If it is indeed a corner
(if (= 14 (car DXFPair))
(progn
;; Get the corner in ICS (converting from PCS to ICS)
(setq CurrentCorner (2DVectorTo3DVector
(list (+ (cadr DXFPair) 0.5)
(- YMax (caddr DXFPair) 0.5)
) ;_ end list
) ;_ end 2DVectorTo3DVector
;; Transform it to WCS and store it
CornerList (cons (3DTransform
ICSXInWCS
ICSYInWCS
ICSZInWCS
ImageInsert
UnitsPerPixelScaleVector
CurrentCorner
) ;_ end 3DTransform
CornerList
) ;_ end cons
) ;_ end setq
) ;_ end progn
) ;_ end if
) ;_ end foreach
;; Put the return value in the proper order
(setq CornerList (reverse CornerList))
) ;_ end progn
) ;_ end if
CornerList
) ;_ end defun
[/php] |
|