Группы пользователей Autodesk

Построение рядов плиток


Создание плиток

 

Создание плиток 
 

Построение рядов плиток



Попробуем разобраться со следующей функцией. Для этого сравним ее с описанным алгоритмом и найдем упомянутые выше геометрические величины. Здесь может встретиться несколько новых функций AutoLISP. Подробнее об этих функциях см. электронный документ AutoLISP Reference. Теперь ознакомимся с кодом (но пока не надо добавлять его в файл).

(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)))

Здесь необходимо пояснить следующее:

  • Ей присваивается точка, выбранная пользователем в качестве начала дорожки.


  • Самый первый аргумент, передаваемый функции gp:calculate-Draw-TileRow, выглядит так:


  • (setq rowStartPoint(polar rowStartPoint pathAngle RowSpacing))

    Иначе говоря, в момент вызова функции gp:calculate-Draw-TileRow точка rowStartPoint переносится на расстояние RowSpacing от текущего положения rowStartPoint.

  • Аргумент rowStartPoint используется в функции gp:calculate-Draw-TileRow в качестве начальной точки для центров кругов в ряде.


  • Для того чтобы компенсировать начальный сдвиг вперед rowStartPoint при рисовании первого ряда (т.е. при первом выполнении цикла while), необходимо слегка передвинуть rowStartPoint в обратном направлении. Благодаря этому удается избежать образования слишком большого пустого пространства между границей дорожки и первым рядом. Точку достаточно сдвинуть на расстояние, равное половине радиуса плитки (TileRadius). Этого можно достичь, используя функцию polar для перемещения точки rowStartPoint вдоль вектора, повернутого на 180 градусов относительно угла PathAngle. При этом точка временно оказывается за пределами границы дорожки.

    Следующий фрагмент (слегка измененный для упрощения чтения) также может вызвать затруднения:

    (setq tileList (append tileList

    (gp:calculate-Draw-TileRow

    (setq rowStartPoint

    (polar rowStartPoint pathAngle RowSpacing)

    ) ;_ end of setq

    TileRadius TileSpace pathWidth pathAngle

    offsetFromCenter ObjectCreationStyle

    )))

    По сути, он представляет собой вызов функции gp:calculate-Draw-TileRow, вложенный в функцию append, которая, в свою очередь, вложена в функцию setq.



    Функция gp:calculate-Draw- TileRow возвращает идентификаторы объектов для построенных плиток. Такими идентификаторами обозначается каждая плитка на рисунке. Плитки строятся ряд за рядом, поэтому функция возвращает идентификаторы объектов сразу для целого ряда. Функция append добавляет их в список tileList.

    Ближе к концу функции можно обнаружить следующий фрагмент кода:

    (setq offsetFromCenter

    (if (= offsetFromCenter 0.0)

    offsetDistance

    0.0

    )

    )

    Этот фрагмент отвечает за рисование рядов плиток в шахматном порядке. Здесь происходит либо совмещение центра средней плитки с центральной линией дорожки, либо сдвиг плиток относительно этой линии. Алгоритм выглядит следующим образом:

    Установить сдвиг равным следующему:

    Если текущий сдвиг равен 0, установить его равным расстоянию сдвига;

    Иначе, установить сдвиг равным 0.

     


    Содержание раздела