行を描画する

次の関数の意味が理解できるかどうか見てみてください。前出の疑似関数と比較して、そこに書かれた幾何学的計算がどれに当たるかを検討してください。初めて目にする 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

コード内の 2 つの部分を、少し説明します。

次のコードが、while ループの開始直前にあります。

;; Compensate for the very first start point!!
(setq rowStartPoint(polar rowStartPoint 
(+ pathAngle pi)(/ TileRadius 2.0)))

このアルゴリズムの背後には、手順を明らかにする次の 3 つの考え方があります。

最初の行の描画中(while ループの最初の実行時)に、rowStartPoint の前方への最初のシフトを行うのは、rowStartPoint を向こう側に少しシフトするためです。これは、歩道の境界と最初の行との間に、何もない大きな余白が生じるのを避けるために行います。TileRadius の 1/2 は、点の移動に十分な量です。これは、polar を使用して、PathAngle から 180 度の方向のベクトルに沿って rowStartPoint を投影することで実現できます。これを考えたとき、点は一時的に境界の外側に配置されます。

次のコード(読みやすく編集されています)は、少し理解し難いかもしれません。

(setq tileList (append tileList
                  (gp:calculate-Draw-TileRow
                    (setq rowStartPoint
                      (polar rowStartPoint pathAngle RowSpacing)
                    ) ;_ end of setq
                    TileRadius TileSpace pathWidth pathAngle
                    offsetFromCenter ObjectCreationStyle
                  ))
)

要するに、setqappend を含み、append は gp:calculate-Draw-TileRow の呼び出しを含んでいます。

gp:calculate-Draw-TileRow 関数は、描かれた各タイルのオブジェクト ID を返します。(オブジェクト ID は、図面内のタイル オブジェクトを指し示します。)行ごとにタイルを描いていくので、この関数は、一度に 1 つの行のオブジェクト ID を返します。append 関数は、新しい オブジェクト ID を、tileList に格納された既存のオブジェクト ID に追加します。

; 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.