看看你是否能理解以下功能。将其与伪代码进行比较,并尝试捕获刚刚描述的几何计算。您可能有一些 AutoLISP 函数对您来说是不熟悉的,如果您需要有关这些功能的帮助,请参阅 AutoLISP 文档。现在,只需阅读代码;不要写任何东西。 (defun gp:Calculate-and-Draw-Tiles (BoundaryData / PathLength
TileSpace TileRadius SpaceFilled SpaceToFill
RowSpacing offsetFromCenter
rowStartPoint pathWidth pathAngle
ObjectCreationStyle TileList)
(setq PathLength (cdr (assoc 41 BoundaryData))
TileSpace (cdr (assoc 43 BoundaryData))
TileRadius (cdr (assoc 42 BoundaryData))
SpaceToFill (- PathLength TileRadius)
RowSpacing (* (+ TileSpace (* TileRadius 2.0))
(sin (Degrees->Radians 60))
) ;_ end of *
SpaceFilled RowSpacing
offsetFromCenter 0.0
offsetDistance (/ (+ (* TileRadius 2.0) TileSpace) 2.0)
rowStartPoint (cdr (assoc 10 BoundaryData))
pathWidth (cdr (assoc 40 BoundaryData))
pathAngle (cdr (assoc 50 BoundaryData))
ObjectCreationStyle (strcase (cdr (assoc 3 BoundaryData)))
) ;_ end of setq
;; Compensate for the first call to gp:calculate-Draw-tile Row
;; in the loop below.
(setq rowStartPoint
(polar rowStartPoint
(+ pathAngle pi)
(/ TileRadius 2.0)
) ;_ end of polar
) ;_ end of setq
;; Draw each row of tiles.
(while (<= SpaceFilled SpaceToFill)
;; Get the list of tiles created, adding them to our list.
(setq tileList
(append tileList
(gp:calculate-Draw-TileRow
(setq rowStartPoint
(polar rowStartPoint
pathAngle
RowSpacing
) ;_ end of polar
) ;_ end of setq
TileRadius
TileSpace
pathWidth
pathAngle
offsetFromCenter
ObjectCreationStyle
) ;_ end of gp:calculate-Draw-TileRow
) ;_ end of append
;; Calculate the distance along the path for the next row.
SpaceFilled
(+ SpaceFilled RowSpacing)
;; Alternate between a zero and a positive offset
;; (causes alternate rows to be indented).
offsetFromCenter
(if (= offsetFromCenter 0.0)
offsetDistance
0.0
) ;_ end of if
) ;_ end of setq
) ;_ end of while
;; Return the list of tiles created.
tileList
) ;_ end of defun
代码中的几个部分可能需要一些额外的解释。 以下代码片段发生在循环开始之前:while ;; Compensate for the very first start point!! (setq rowStartPoint(polar rowStartPoint (+ pathAngle pi)(/ TileRadius 2.0))) 找出该算法背后的逻辑的难题分为三部分:
为了补偿在绘制第一行期间(即通过循环的第一个循环)期间的初始前移,您需要向相反方向略微移动。目的是避免在路径边界和第一行之间出现较大的空白空间。一半的量足以移动点。这可以通过使用沿面向180度的矢量投影来实现。如果您考虑一下,这会将点暂时置于路径边界之外。rowStartPointwhilerowStartPointTileRadiuspolarrowStartPointPathAngle 下一个片段(为可读性而修改)可能有点令人费解: (setq tileList
(append tileList
(gp:calculate-Draw-TileRow
(setq rowStartPoint
(polar rowStartPoint pathAngle RowSpacing)
) ;_ end of setq
TileRadius
TileSpace
pathWidth
pathAngle
offsetFromCenter
ObjectCreationStyle
)
)
)
从本质上讲,有包裹的,环绕着的调用。setqappendgp:calculate-Draw-TileRow 该函数将返回绘制的每个图块的对象 ID。(对象 ID 指向图形中的平铺对象。您正在逐行绘制磁贴,因此该函数一次返回一行的对象 ID。该函数将新的对象 ID 添加到存储在其中的任何现有对象 ID。gp:calculate-Draw-TileRowappendtileList ; Near the end of the function, you can find the following code fragment:
(setq offsetFromCenter
(if (= offsetFromCenter 0.0)
offsetDistance
0.0
)
)
这是偏移切换开关,它确定要绘制的行是以路径为中心的圆还是从路径偏移开始。此算法的伪代码如下: ; Set the offset amount to the following: ; If the offset is currently zero, set it to the offset distance; ; Otherwise, set it back to zero. |
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-10-29 14:13
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.