"Мышца" и ее сокращение
Пусть объект в трехмерном пространстве задан своей оболочкой. Каждый элемент оболочки является клеткой. Оболочка формируется при создании объекта. В общем случае объект может быть заполнен значащей информацией и внутри, если его вид в разрезе интересует пользователя.
"Мышца" (далее кавычки опустим) как рычаг управления деформацией объекта задается пользователем-разработчиком в центральной системе координат координатами начала и конца, а также точкой неподвижности, относительно которой возможно сокращение мышцы. Точка неподвижности может совпадать с началом или концом мышцы. (Конечно указанные точки обозначаются мышью; координаты при этом выставляются автоматически.) По умолчанию точка неподвижности является серединой мышцы. Мышца не обязательно связывает точки оболочки. В общем случае она может располагаться внутри и даже вне объекта, принадлежа ему и влияя на его деформацию.
Мышцы объекта являются невидимыми, входящими в список мышц данного объекта и допускающими реакцию на приказы извне.
Рис. 15.2. Применение мышцы
Таким образом, мышца (рис. 15.2) — это невидимый отрезок АВ, связывающий точки A(x1, y1, z1) и B(x2, y2, z2) , отображающий некоторое геометрическое место клеток объекта. Этот отрезок связан с объектом и может сокращаться при подаче управляющих импульсов и восстанавливаться при их отсутствии. Такое изменение отрезка производится относительно некоторой принадлежащей ему точки М(xM, yM, zM) . Сокращение мышцы сопровождается пространственным переносом (уплотнением) клеток объекта, которые принадлежат (с точностью до дискретности адресации) отрезку, обозначающему эту мышцу.
Параметрическая система уравнений, описывающих отрезок АВ, имеет вид
(15.1) |
Напоминаем, что координаты точек объекта совпадают с адресами памяти, по которым находятся соответствующие клетки, так что систему уравнений (15.1) с точностью до целочисленной дискретности адресации можно рассматривать относительно трехмерных адресов . Это и подразумевается в дальнейших выкладках.
Пусть l — коэффициент сжатия мышцы. Тогда отрезок АМ необходимо преобразовать в отрезок А*М с длиной l·|А*М|, а отрезок МВ — в отрезок МВ* с длиной l· |МВ*|.
Рассматривая по каждой координате отдельно, убеждаемся, что отрезок x1xM
необходимо преобразовать в отрезок x1* xM
с длиной l(xM- x1) , отрезок xMx2
необходимо преобразовать в отрезок xMx2* c длиной l(x2
- xM) . Аналогично отрезок y1yM
должен быть преобразован в отрезок y1* yM
с длиной l(yM - y1) и т.д.
Это, в частности, означает, что клетка с координатой x1
должна быть переслана в ячейку, определяемую соответствующей составляющей адреса l(xM
- x1) и т.д.
Здесь граничное значение цикла определяется максимальным значением точек переноса по всем координатам, равным ?А + 1. Программно перенос производится с конца отрезка к его началу — чтобы не уничтожать еще не перенесенную информацию. Тогда адреса переноса отдельно по координатам находятся как
(15.2) |
051 - 1 · 0,610 · 0,510 = 051 051 - 2 · 0,610 · 0,510 = 050 051 - 3 · 0,610 · 0,510 = 050 051 - 4 · 0,610 · 0,510 = 050 051 - 5 · 0,610 · 0,510 = 047 051 - 6 · 0,610 · 0,510 = 047 051 - 7 · 0,610 · 0,510 = 046 051 - 10 · 0,610 · 0,510 = 046 051 - 11 · 0,610 · 0,510 = 046
Рассчитаем координату у:
461 - 1 · 0,610 · 1 = 460 461 - 2 · 0,610 · 1 = 460 461 - 3 · 0,610 · 1 = 457 461 - 4 · 0,610 · 1 = 456 461 - 5 · 0,610 · 1 = 456 461 - 6 · 0,610 · 1 = 455 461 - 7 · 0,610 · 1 = 454 461 - 10 · 0,610 · 1 = 453 461 - 11 · 0,610 · 1 = 452
Адреса переноса по координате z:
716 - 1 · 0,610 · 0,2510 = 716 716 - 2 · 0,610 · 0,2510 = 716 716 - 3 · 0,610 · 0,2510 = 716 716 - 4 · 0,610 · 0,2510 = 716 716 - 5 · 0,610 · 0,2510 = 715 716 - 6 · 0,610 · 0,2510 = 715 716 - 7 · 0,610 · 0,2510 = 715 716 - 10 · 0,610 · 0,2510 = 715 716 - 11 · 0,610 · 0,2510 = 715
Найдены адреса, по которым необходимо осуществить пересылку при сокращении левой части мышцы.
Аналогично, для правой части мышцы, для отрезка МВ, найдем адресные расстояния ?Ax
= -4 , ?Ay = -10 = -810
, ?Az
= -2 , ?А = -810
. По (15.2) для адресов переноса по x, y, z находим
051 + 1 · 0,610 · 0,510 = 051 461 + 1 · 0,610 · 1 = 462 716 + 1 · 0,610 · 0,2510 = 716 051 + 2 · 0,610 · 0,510 = 052 461 + 2 · 0,610 · 1 = 463 716 + 2 · 0,610 · 0,2510 = 716 051 + 3 · 0,610 · 0,510 = 052 461 + 3 · 0,610 · 1 = 463 716 + 3 · 0,610 · 0,2510 = 716 051 + 4 · 0,610 · 0,510 = 052 461 + 4 · 0,610 · 1 = 464 716 + 4 · 0,610 · 0,2510 = 716 051 + 5 · 0,610 · 0,510 = 053 461 + 5 · 0,610 · 1 = 464 716 + 5 · 0,610 · 0,2510 = 717 051 + 6 · 0,610 · 0,510 = 053 461 + 6 · 0,610 · 1 = 465 716 + 6 · 0,610 · 0,2510 = 717 051 + 7 · 0,610 · 0,510 = 053 461 + 7 · 0,610 · 1 = 465 716 + 7 · 0,610 · 0,2510 = 717 051 + 10 · 0,610 · 0,510 = 054 461 + 10 · 0,610 · 1 = 466 716 + 10 · 0,610 · 0,2510 = 717 051 + 11 · 0,610 · 0,510 = 054 461 + 11 · 0,610 · 1 = 466 716 + 11 · 0,610 · 0,2510 = 717
Таким образом, найдены адреса ячеек памяти, куда следует пересылать информацию при сокращении мышцы. Необходимо выяснить, какие точки отрезка, отображающего мышцу, необходимо пересылать по найденным адресам.
Свяжем перебор искомых точек с тем же параметром цикла организации пересылки
(15.3) |
051 - 1 · 0,510 = 050 461 - 1 · 1 = 460 716 - 1 · 0,2510 = 716 051 - 2 · 0,510 = 050 461 - 2 · 1 = 457 716 - 2 · 0,2510 = 715 051 - 3 · 0,510 = 047 461 - 3 · 1 = 456 716 - 3 · 0,2510 = 715 051 - 4 · 0,510 = 047 461 - 4 · 1 = 455 716 - 4 · 0,2510 = 715 051 - 5 · 0,510 = 046 461 - 5 · 1 = 454 716 - 5 · 0,2510 = 715 051 - 6 · 0,510 = 046 461 - 6 · 1 = 453 716 - 6 · 0,2510 = 714 051 - 7 · 0,510 = 045 461 - 7 · 1 = 452 716 - 7 · 0,2510 = 714 051 - 10 · 0,510 = 045 461 - 10 · 1 = 451 716 - 10 · 0,2510 = 714 051 - 11 · 0,510 = 045 461 - 11 · 1 = 450 716 - 11 · 0,2510 = 714
Для отрезка МВ находим
051 + 1 · 0,510 = 052 461 + 1 = 462 716 + 1 · 0,2510 = 716 051 + 2 · 0,510 = 052 461 + 2 = 463 716 + 2 · 0,2510 = 716 051 + 3 · 0,510 = 053 461 + 3 = 464 716 + 3 · 0,2510 = 716 051 + 4 · 0,510 = 053 461 + 4 = 465 716 + 4 · 0,2510 = 716 051 + 5 · 0,510 = 054 461 + 5 = 466 716 + 5 · 0,2510 = 716 051 + 6 · 0,510 = 054 461 + 6 = 467 716 + 6 · 0,2510 = 716 051 + 7 · 0,510 = 055 461 + 7 = 470 716 + 7 · 0,2510 = 716 051 + 10 · 0,510 = 055 461 + 10 = 471 716 + 10 · 0,2510 = 716 051 + 11 · 0,510 = 055 461 + 11 = 471 716 + 11 · 0,2510 = 716
"Склеим" координатные части адресов и обозначим ее окончательно в двух столбцах: в левом — пересылку для левой части мышцы, в правом — для правой.
(050 460 716) 051 460 716 (052 462 716) 051 462 716 (050 457 715) 050 460 716 (052 463 717) 052 463 716 (047 456 715) 050 457 716 (053 464 717) 052 463 716 (047 455 715) 050 456 716 (053 465 717) 052 464 716 (046 454 715) 047 456 715 (054 466 717) 053 464 717 (046 453 714) 047 455 715 (054 467 720) 053 465 717 (045 452 714) 046 454 715 (055 470 720) 053 465 717 (045 451 714) 046 453 715 (055 471 720) 054 466 717 (045 450 714) 046 452 715 (055 471 720) 054 466 717
В строках 2 и 3, в 6 и 7, а также в 8 и 9 видно формирование стеков при неоднократной записи в одну клетку.
Однако вся проделанная выше работа по сжатию мышцы в действительности касается только клеток со значащим содержимым. Это означает, что если объект задан своей оболочкой, то переносу подвергаются только клетки оболочки. Мышца чаще всего является "пустым" объектом, и смещаются только точки А и В. Переносить ее клетки следует в таком случае лишь тогда, когда она принадлежит оболочке или пересекается с ней.
Сокращение мышцы можно использовать для деформации объекта на стадии его создания. После этого мышца может быть исключена из списка объекта или переопределена вновь в измененных границах.
Таким образом, каждый перенос клетки мышцы или объекта в целом сопровождается анализом на значимость этой клетки.