Консолидированные перемещения в векторной графике
Сюда, в частности, относится режим передвижения выбранных точек, отрезков и прочих элементов графики по осям X,Y,Z с помощью клавиш со стрелочками в правой части панели ноутбука.
Указанный режим я расширил. Теперь можно передвигать не только единственный выбранный элемент целиком, но и передвигать вместе с ним другие элементы, имеющие тот же цвет.
И это удобно – мы можем, например, нарисовать чёрный скелет, а руку изобразить коричневым цветом и, передвигая её, приделывать к скелету так, как это нам нужно. Режим консолидированного перемещения по цвету вводится постановкой значка # на кнопке активного цвета.
Если же, при значке #, кликом по кнопке блокировки рисования установить на ней тёмный цвет, тогда путём нажатия клавиш можно передвигать всю модель целиком.
В точности по такой же схеме я расширил действия по пункту меню «Вращение выбранного элемента вокруг отрезка прямой». В основе этого преобразования лежит поворот вектора путём умножения его компонент на матрицу поворота.
Коэффициенты матрицы вычисляются так, как это показано на иллюстрации. Там X,Y,Z – компоненты единичного вектора, совпадающего с осью поворота, а буквы S,C обозначают синус и косинус угла поворота.
Текст подпрограммы, осуществляющей поворот, приведён ниже. Обратите внимание, с помощью этой же подпрограммы можно проводить не только поворот единичного выбранного элемента, но и одновременно поворачивать все элементы, совпадающие с ним по цвету, а также поворачивать всю модель целиком.
Кроме того, я ввёл в меню пункт «Расширение и сближение элементов» вокруг выбранной точки, или в направлении вдоль выбранного отрезка (если выбран отрезок, а не точка). Текст подпрограммы, осуществляющей такие преобразования тоже приводится ниже.
Иллюстрация демонстрирует, как я, работая с этими пунктами меню, сначала уменьшил череп в размерах, приблизив все его элементы к красной точке, а затем увеличил размер модели вдоль оси, указанной зелёным отрезком.
Обратите внимание – длина зелёного отрезка тоже увеличилась.
Затем я поставил зелёный отрезок вертикально и повернул модель вокруг него.
Описанные консолидированные действия с векторной графикой по признаку её цвета оказываются практически очень удобными, и могут быть рекомендованы к использованию в аналогичных случаях.
==========
ПРИЛОЖЕНИЕ. Тексты подпрограмм.
ПОЯСНЕНИЯ.
В предлагаемых текстах Pvv(N, K) – строки массива, в котором в форме целых чисел хранится векторная графика. Pvv(N, 0) – логотип элемента. 1-точка, 2-отрезок, 3-прямая (отрезок с длинными продолжениями за его концы), 4-плоскость (точка и единичный вектор – нормаль к плоскости, 5,6 – сечения.
Начальные координаты X,Y,Z следуют за логотипом, далее могут быть координаты второй точки или компоненты единичного вектора (для плоскости). Цвет эл-та находится в Pvv(N, 10).
Public Sub Act10() 'точка или прямая вращается вокруг отрезка на угол CV*10 градусов Ngg(3,2) 0-L 1-№ 2-цвет '
Dim I As Integer, N1 As Integer, J As Integer, N As Integer
Dim X As Single, Y As Single, Z As Single, X1 As Single, Y1 As Single, Z1 As Single
Dim L As Single, U As Single, S As Single, C As Single, Lo As Integer
Dim M11 As Single, M12 As Single, M13 As Single, M21 As Single, M22 As Single, M23 As Single
Dim M31 As Single, M32 As Single, M33 As Single, Xo As Single, Yo As Single, Zo As Single
Dim F As Integer, CC As Integer 'флаг и цвет
J = Ngg(1, 1): N1 = Mvv(J, 0):
F = 0: If Form1.Command5.Caption = Chr(35) Then F = 1: CC = Pvv(N1, 10) 'если #
J = Ngg(2, 1): N = Mvv(J, 0): L = Lab(N) * 10: If L < 50 Then Exit Sub
For I = 0 To 12: Sm3(I) = Pvv(N1, I): Next I: Sm3(13) = N1:
Xo = Pvv(N, 1): Yo = Pvv(N, 2): Zo = Pvv(N, 3):
X = (Pvv(N, 4) - Pvv(N, 1)) / L: J = CV * 10: If J = 0 Then J = 5: 'угол поворота
Y = (Pvv(N, 5) - Pvv(N, 2)) / L: Z = (Pvv(N, 6) - Pvv(N, 3)) / L:
U = J: If F = 1 Then U = U / 50
S = Sin(U * pi180): C = Cos(U * pi180)
M11 = C + (1 - C) * X * X: M12 = (1 - C) * X * Y - S * Z: M13 = (1 - C) * X * Z + S * Y:
M21 = (1 - C) * Y * X + S * Z: M22 = C + (1 - C) * Y * Y: M23 = (1 - C) * Y * Z - S * X:
M31 = (1 - C) * Z * X - S * Y: M32 = (1 - C) * Z * Y + S * X: M33 = C + (1 - C) * Z * Z:
If F = 0 Then Lo = Pvv(N1, 0): GoTo 2
For N1 = 1 To NPv: Lo = Pvv(N1, 0): If Lo = 0 Then GoTo 3
If N1 = N Then GoTo 3
If FC36 = 0 And Pvv(N1, 10) <> CC Then GoTo 3
2 I = 1: GoSub 9: Pvv(N1, 1) = X1: Pvv(N1, 2) = Y1: Pvv(N1, 3) = Z1
If Lo > 1 And Lo < 5 Then I = 4: GoSub 9: Pvv(N1, 4) = X1: Pvv(N1, 5) = Y1: Pvv(N1, 6) = Z1
If F = 0 Then GoTo 4:
3 Next N1: Form1.Text2 = " эл-ты повёрнуты на" + vbNewLine + Str(U) + "гр.": GoTo 5
4 Form1.Text2 = " эл-т повёрнут на" + Str(J) + "гр." + vbNewLine + " отменить? ДА":
5 Form1.Picture1.Line (1, 1)-(Kw, Kh), C240, BF: Call VPrun(3): Exit Sub
9 X = Pvv(N1, I): Y = Pvv(N1, I + 1): Z = Pvv(N1, I + 2):
If I = 4 And Lo = 4 Then Else X = X - Xo: Y = Y - Yo: Z = Z - Zo:
X1 = M11 * X + M12 * Y + M13 * Z:
Y1 = M21 * X + M22 * Y + M23 * Z:
Z1 = M31 * X + M32 * Y + M33 * Z: If I = 4 And Lo = 4 Then Return 'если 1-й вектор к плоскости
X1 = X1 + Xo: Y1 = Y1 + Yo: Z1 = Z1 + Zo: Return
‘============
Public Sub Act11p(N As Integer, M As Single, L As Single) 'п/п удаления/сближения
Dim Xo As Single, Yo As Single, Zo As Single, X As Single, Y As Single, Z As Single, C As Integer
Dim I As Integer, K As Integer, Lo As Integer, F As Integer
Dim Lx As Single, Ly As Single, Lz As Single, SC As Single, dL As Single
Xo = Pvv(N, 1): Yo = Pvv(N, 2): Zo = Pvv(N, 3): C = Pvv(N, 10):
If L > 0 Then Lx = (Pvv(N, 4) - Xo) / L: Ly = (Pvv(N, 5) - Yo) / L: Lz = (Pvv(N, 6) - Zo) / L:
F = 0: If Form1.Command5.Caption = Chr(35) Then F = 1: 'если знак #
For I = 1 To NPv: Lo = Pvv(I, 0): If Lo = 0 Then GoTo 5
If Lo > 4 Then GoTo 5
If F = 0 Then If C <> Pvv(I, 10) Then GoTo 5
K = 1: GoSub 9:
If Lo = 2 Or Lo = 3 Then K = 4: GoSub 9:
5 Next I:
Form1.Picture1.Line (1, 1)-(Kw, Kh), C240, BF: Call VPrun(3):
If CV < 5 Then Form1.Text2 = " эл-ты сближены" Else Form1.Text2 = " эл-ты расширены":
Exit Sub: '========================
9 X = Pvv(I, K) - Xo: Y = Pvv(I, K + 1) - Yo: Z = Pvv(I, K + 2) - Zo:
If L > 0 Then GoTo 10
X = X * M: Y = Y * M: Z = Z * M:
Pvv(I, K) = X + Xo: Pvv(I, K + 1) = Y + Yo: Pvv(I, K + 2) = Z + Zo:
Return
10 SC = X * Lx + Y * Ly + Z * Lz: dL = SC * M - SC:
Pvv(I, K) = X + dL * Lx + Xo:
Pvv(I, K + 1) = Y + dL * Ly + Yo:
Pvv(I, K + 2) = Z + dL * Lz + Zo:
Return
End Sub
________________
Свидетельство о публикации №222082601315