Компьютерная графика. 4
Алгоритм №1
Поворот фигуры вокруг вертикальной оси с помощью алгоритма Робертса
Алгоритм №2
Пересечения фигуры и куба.
Алгоритм №1
Поворот фигуры вокруг вертикальной оси с помощью алгоритма Робертса
Для алгоритма Робертса в первую очередь составим матрицу тела:
Определим все вершины многогранника, так, чтобы центр начала координат находился в центре фигуры
Координаты точек:
А(-10;-10;-10);
B(10;-10;-10);
C(10;10;-10);
D(-10;10;-10);
А1(-10;-10;0);
B1(10;-10;0);
C1(10;10;0);
D1(-10;10;0);
А2(-5;-5;10);
B2(5;-5;10);
C2(5;5;10);
D2(-5;5;10);
Составим и решим с помощью Exel уравнения плоскостей, для этого возьмем по 3 точек с каждой плоскости:
А(-10;-10;-10) = -10a-10b-10с=-1
B(10;-10;-10)= = 10a-10b-10с=-1
C(10;10;-10)= 10a+10b-10с=-1
D(-10;10;-10)= -10a+10b-10с=-1
А1(-10;-10;0)= -10a-10b=-1
B1(10;-10;0)= 10a-10b=-1
C1(10;10;0)= 10a+10b=-1
D1(-10;10;0)= -10a+10b=-1
А2(-5;-5;10)= -5a-5b+10с=-1
B2(5;-5;10)= 5a-5b+10с=-1
C2(5;5;10)= 5a+5b+10с=-1
D2(-5;5;10)= -5a+5b+10с=-1
| 1 |
| 2 | ||||||||||||||||||||||||||||
B | 10 | -10 | -10 |
| -1 | A | -10 | -10 | -10 |
| -1 | ||||||||||||||||||||
B1 | 10 | -10 | 0 |
| -1 | A1 | -10 | -10 | 0 |
| -1 | ||||||||||||||||||||
C1 | 10 | 10 | 0 |
| -1 | D1 | -10 | 10 | 0 |
| -1 | ||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||||||||
| 0 | 0,05 | 0,05 | a= | -0,1 |
| 0 | -0,05 | -0,05 | a= | 0,1 | ||||||||||||||||||||
| 0 | -0,05 | 0,05 | b= | 0 |
| 0 | -0,05 | 0,05 | b= | 0 | ||||||||||||||||||||
| -0,1 | 0,1 | 0 | c= | 0 |
| -0,1 | 0,1 | 0 | c= | 0 | ||||||||||||||||||||
| 3 |
| 4 | ||||||||||||||||||||||||||||
D1 | -10 | 10 | 0 |
| -1 | A | -10 | -10 | -10 |
| -1 | ||||||||||||||||||||
C1 | 10 | 10 | 0 |
| -1 | A1 | -10 | -10 | 0 |
| -1 | ||||||||||||||||||||
C | 10 | 10 | -10 |
| -1 | B1 | 10 | -10 | 0 |
| -1 | ||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||||||||
| -0,05 | 0,05 | 0 | a= | 0 |
| 0 | -0,05 | 0,05 | a= | 0 | ||||||||||||||||||||
| 0,05 | 0,05 | 0 | b= | -0,1 |
| 0 | -0,05 | -0,05 | b= | 0,1 | ||||||||||||||||||||
| 0 | 0,1 | -0,1 | c= | 0 |
| -0,1 | 0,1 | 0 | c= | 0 | ||||||||||||||||||||
| 5 |
| 7 | ||||||||||||||||||||||||||||
A2 | -5 | -5 | 10 |
| -1 | B2 | 5 | -5 | 10 |
| -1 | ||||||||||||||||||||
b2 | 5 | -5 | 10 |
| -1 | B1 | 10 | -10 | 0 |
| -1 | ||||||||||||||||||||
C2 | 5 | 5 | 10 |
| -1 | C1 | 10 | 10 | 0 |
| -1 | ||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||||||||
| -0,1 | 0,1 | 0 | a= | 0 |
| 0 | 0,05 | 0,05 | a= | -0,1 | ||||||||||||||||||||
| 0 | -0,1 | 0,1 | b= | 0 |
| 0 | -0,05 | 0,05 | b= | 0 | ||||||||||||||||||||
| 0,05 | 0 | 0,05 | c= | -0,1 |
| 0,1 | -0,05 | 0 | c= | -0,05 | ||||||||||||||||||||
| 6 | 8 | |||||||||||||||||||||||||||||
A | -10 | -10 | -10 |
| -1 | A2 | -5 | -5 | 10 |
| -1 | ||||||||||||||||||||
B | 10 | -10 | -10 |
| -1 | A1 | -10 | -10 | 0 |
| -1 | ||||||||||||||||||||
C | 10 | 10 | -10 |
| -1 | D1 | -10 | 10 | 0 |
| -1 | ||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||||||||
| -0,05 | 0,05 | 0 | a= | 0 |
| 0 | -0,05 | -0,05 | a= | 0,1 | ||||||||||||||||||||
| 0 | -0,05 | 0,05 | b= | 0 |
| 0 | -0,05 | 0,05 | b= | 0 | ||||||||||||||||||||
| -0,05 | 0 | -0,05 | c= | 0,1 |
| 0,1 | -0,05 | 0 | c= | -0,05 | ||||||||||||||||||||
| 9 | 10 | |||||||||||||||||||||||||||||
D1 | -10 | 10 | 0 |
| -1 | A1 | -10 | -10 | 0 |
| -1 | ||||||||||||||||||||
C1 | 10 | 10 | 0 |
| -1 | B1 | 10 | -10 | 0 |
| -1 | ||||||||||||||||||||
C2 | 5 | 5 | 10 |
| -1 | B2 | 5 | -5 | 10 |
| -1 | ||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
| ||||||||||||||||||||
| -0,05 | 0,05 | 0 | a= | 0 |
| -0,05 | 0,05 | 0 | a= | 0 | ||||||||||||||||||||
| 0,05 | 0,05 | 0 | b= | -0,1 |
| -0,05 | -0,05 | 0 | b= | 0,1 | ||||||||||||||||||||
| 0 | -0,05 | 0,1 | c= | -0,05 |
| 0 | -0,05 | 0,1 | c= | -0,05 | ||||||||||||||||||||
На основании вычислений, запишем матрицу тела:
-0,1 | 0,1 | 0 | 0 | 0 | 0 | -0,1 | 0,1 | 0 | 0 |
0 | 0 | -0,1 | 0,1 | 0 | 0 | 0 | 0 | -0,1 | 0,1 |
0 | 0 | 0 | 0 | -0,01 | 0,1 | -0,05 | -0,05 | -0,05 | -0,05 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Эту матрицу тела следует проверить с помощью одной из тех точек, о которых известно, что они лежат внутри тела, чтобы убедиться, что знаки каждого уравнения плоскости выбраны верно. Если знак скалярного произведения для какой-нибудь плоскости меньше нуля, то соответствующее уравнение плоскости следует умножить на - 1. Точка внутри куба с координатами х = 0,5, у = 0,5, z = 0,5
Скалярное произведение этого вектора на матрицу объема равно:
[S]×[V] =
-0,1 | 0,1 | 0 | 0 | 0 | 0 | -0,1 | 0,1 | 0 | 0 |
0 | 0 | -0,1 | 0,1 | 0 | 0 | 0 | 0 | -0,1 | 0,1 |
0 | 0 | 0 | 0 | -0,01 | 0,1 | -0,05 | -0,05 | -0,05 | -0,05 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
* |
|
|
|
|
|
|
|
|
|
0,5 | 0,5 | 0,5 | 1 |
|
|
|
|
|
|
= |
|
|
|
|
|
|
|
|
|
0,95 | 1,05 | 0,95 | 1,05 | 0,995 | 1,05 | 0,925 | 1,025 | 0,925 | 1,025 |
Отрицательных результатов не – матрица корректна.
Умножим матрицу тела на вектор наблюдателя получим матрицу, элементы которой знаком показывают видимость граней
| матрица тела |
|
|
|
|
|
|
|
|
|
| |
грани | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|
|
| -0,1 | 0,1 | 0 | 0 | 0 | 0 | -0,1 | 0,1 | 0 | 0 |
|
|
| 0 | 0 | -0,1 | 0,1 | 0 | 0 | 0 | 0 | -0,1 | 0,1 |
|
|
| 0 | 0 | 0 | 0 | -0 | 0,1 | -0,05 | -0,05 | -0,05 | -0,05 |
|
|
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|
|
вектор наблюдателя Е |
| скалярное произведение VE |
|
|
| |||||||
x | -0,89239 | грани | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
y | -1 |
| 0,1 | -0 | 0 | -0 | 0,005 | -0,045 | 0,1 | -0 | 0,1 | -0 |
z | -0,45127 |
| видимые грани имеют положительное значение | |||||||||
| 0 |
|
|
|
|
|
|
|
|
|
|
|
Программа на VBA:
В первой функции выражаем координаты всех точек фигуры через заданную точку xa=-20, ya=-20, za=-20 и заданную длину, ширину и высоту фигуры.
Затем передаем из в функцию поворотZ а затем в следующую функцию шестигранник, каждый раз меняя вектор наблюдения:
Public Sub поворот_кубика_вокруг_осиZ()
For gamma = 0 To 7 Step 0.4
Range("A1:iv200").Interior.
Call оси
'координата нижней точки A
xa = -20: ya = -20: za = -20
dlina = 40 '
vusota = 20
vusota2 = 40
shirina = 40
'определенние координат всех вершин
xb = xa + dlina: yb = ya: zb = za
xc = xb: yc = ya + shirina: zc = za
xd = xa: yd = yc: zd = za
xa1 = xa: ya1 = ya: za1 = za + vusota
xb1 = xb: yb1 = yb: zb1 = zb + vusota
xc1 = xc: yc1 = yc: zc1 = zc + vusota
xd1 = xd: yd1 = yd: zd1 = zd + vusota
xa2 = xa + 10: ya2 = ya + 5: za2 = za1 + vusota2
xb2 = xb1 - 10: yb2 = ya2: zb2 = za2
xc2 = xb2: yc2 = yc1 - 10: zc2 = za2
xd2 = xa2: yd2 = yc2: zd2 = za2
'угол наблюдения за кубиком в радианах от иси х
gammaNabl = 0.985
'поворот всех точек
Call поворотZ(gamma, xa, ya, za, xa, ya, za)
Call поворотZ(gamma, xb, yb, zb, xb, yb, zb)
Call поворотZ(gamma, xc, yc, zc, xc, yc, zc)
Call поворотZ(gamma, xd, yd, zd, xd, yd, zd)
Call поворотZ(gamma, xa1, ya1, za1, xa1, ya1, za1)
Call поворотZ(gamma, xb1, yb1, zb1, xb1, yb1, zb1)
Call поворотZ(gamma, xc1, yc1, zc1, xc1, yc1, zc1)
Call поворотZ(gamma, xd1, yd1, zd1, xd1, yd1, zd1)
Call поворотZ(gamma, xa2, ya2, za2, xa2, ya2, za2)
Call поворотZ(gamma, xb2, yb2, zb2, xb2, yb2, zb2)
Call поворотZ(gamma, xc2, yc2, zc2, xc2, yc2, zc2)
Call поворотZ(gamma, xd2, yd2, zd2, xd2, yd2, zd2)
'для определениня видимых граней изменяем точку наблюденипя
'корректируем вектор Е
Worksheets("видимые грани").Range("B8").Value = -Cos(gammaNabl - gamma)
Worksheets("видимые грани").Range("B10").Value = -Sin(gammaNabl - gamma)
'рисуем фигуру
Call шестигранник(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd, _
xa1, ya1, za1, xb1, yb1, zb1, xc1, yc1, zc1, xd1, yd1, zd1, xa2, _
ya2, za2, xb2, yb2, zb2, xc2, yc2, zc2, xd2, yd2, zd2)
Next gamma
End Sub
В следующей функции, проверяем на видимость грани с листа «Видимые грани». Если грань видима, то передаем координаты ее точек в функцию четырехугольникXYZ:
Sub шестигранник(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd, _
xa1, ya1, za1, xb1, yb1, zb1, xc1, yc1, zc1, xd1, yd1, zd1, xa2, _
ya2, za2, xb2, yb2, zb2, xc2, yc2, zc2, xd2, yd2, zd2)
gran1 = False
gran2 = False
gran3 = False
gran4 = False
gran5 = False
gran6 = False
gran7 = False
gran8 = False
gran9 = False
gran10 = False
If Worksheets("видимые грани").Range("d9") > 0 Then gran1 = True
If Worksheets("видимые грани").Range("e9") > 0 Then gran2 = True
If Worksheets("видимые грани").Range("f9") > 0 Then gran3 = True
If Worksheets("видимые грани").Range("g9") > 0 Then gran4 = True
If Worksheets("видимые грани").Range("h9") > 0 Then gran5 = True
If Worksheets("видимые грани").Range("i9") > 0 Then gran6 = True
If Worksheets("видимые грани").Range("j9") > 0 Then gran7 = True
If Worksheets("видимые грани").Range("k9") > 0 Then gran8 = True
If Worksheets("видимые грани").Range("l9") > 0 Then gran9 = True
If Worksheets("видимые грани").Range("m9") > 0 Then gran10 = True
'отображение на экране 1 грани
If gran1 = True Then
RGBcolor = 12
Call четырехугольникXYZ(xb1, yb1, zb1, xb, yb, zb, xc, yc, zc, xc1, yc1, zc1)
End If
'отображение на экране 2 грани
If gran2 = True Then
RGBcolor = 11
Call четырехугольникXYZ(xa1, ya1, za1, xa, ya, za, xd, yd, zd, xd1, yd1, zd1)
End If
'отображение на экране 3 грани
If gran3 = True Then
RGBcolor = 10
Call четырехугольникXYZ(xd, yd, zd, xd1, yd1, zd1, xc1, yc1, zc1, xc, yc, zc)
End If
'отображение на экране 4 грани
If gran4 = True Then
RGBcolor = 8
Call четырехугольникXYZ(xa1, ya1, za1, xa, ya, za, xb, yb, zb, xb1, yb1, zb1)
End If
'отображение на экране 5 грани
If gran5 = True Then
RGBcolor = 9
Call четырехугольникXYZ(xa2, ya2, za2, xb2, yb2, zb2, xc2, yc2, zc2, xd2, yd2, zd2)
End If
If gran6 = True Then
RGBcolor = 6
Call четырехугольникXYZ(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd)
End If
If gran7 = True Then
RGBcolor = 6
Call четырехугольникXYZ(xb1, yb1, zb1, xc1, yc1, zc1, xc2, yc2, zc2, xb2, yb2, zb2)
End If
'отображение на экране 8 грани
If gran8 = True Then
RGBcolor = 7
Call четырехугольникXYZ(xa1, ya1, za1, xa2, ya2, za2, xd2, yd2, zd2, xd1, yd1, zd1)
End If
'отображение на экране 9 грани
If gran9 = True Then
RGBcolor = 15
Call четырехугольникXYZ(xd1, yd1, zd1, xd2, yd2, zd2, xc2, yc2, zc2, xc1, yc1, zc1)
End If
'отображение на экране 10 грани
If gran10 = True Then
RGBcolor = 10
Call четырехугольникXYZ(xa2, ya2, za2, xa1, ya1, za1, xb1, yb1, zb1, xb2, yb2, zb2)
End If
End Sub
результат:
Алгоритм №2
Пересечения фигуры и куба.
В первой функции отчистим экран от прежних значений и заполним его значениями фона 10000. Указываем координаты точки А и длину, высоту и ширину фигуры.
Вызов функции Zvoksel, с передачей в нее координаты дальней точки и длины, высоты и ширины.
Sub Z()
Worksheets("экран").Range("A1:
'очистка буфера кадра
Worksheets("кадр").Range("A1:
'заполнение Z буфера фоновым значением
For x = 1 To 200
For y = 1 To 200
Worksheets("zbyf").Cells(y, x) = 10000
Next y
Next x
Worksheets("кадр").Range("A1:
RGBcolor = 8
Call Zvoksel(0, 0, 0, 40, 40, 40)
Call экран_буфер_кадра(50, 200, 50, 200)
End Sub
В функци Zvoksel определяем координаты всех точек относительно точки А, и передаем их в следующую функцию Zшестигранник
Sub Zvoksel(xa, ya, za, dlina, shirina, vusota)
xb = xa + dlina: yb = ya: zb = za
xc = xb: yc = ya + shirina: zc = za
xd = xa: yd = ya + shirina: zd = za
xa1 = xa + 10: ya1 = ya + 10: za1 = za + vusota
xb1 = xb - 10: yb1 = yb + 10: zb1 = zb + vusota
xc1 = xc - 10: yc1 = yc - 10: zc1 = zc + vusota
xd1 = xd + 10: yd1 = yd - 10: zd1 = zd + vusota
xa2 = xa: ya2 = ya: za2 = za - 20
xb2 = xb: yb2 = yb: zb2 = zb - 20
xc2 = xc: yc2 = yc: zc2 = zc - 20
xd2 = xd: yd2 = yd: zd2 = zd - 20
Call Zшестигранник(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd, _
xa1, ya1, za1, xb1, yb1, zb1, xc1, yc1, zc1, xd1, yd1, zd1, _
xa2, ya2, za2, xb2, yb2, zb2, xc2, yc2, zc2, xd2, yd2, zd2)
End Sub
В функции Zшестигранник определяем грани и передаем их вершины в функции рисования граней, в зависимости от положения грани.
Sub Zшестигранник(xa, ya, za, xb, yb, zb, xc, yc, zc, xd, yd, zd, _
xa1, ya1, za1, xb1, yb1, zb1, xc1, yc1, zc1, xd1, yd1, zd1, _
xa2, ya2, za2, xb2, yb2, zb2, xc2, yc2, zc2, xd2, yd2, zd2)
Call Z_четырехугольник(xa, ya, za, xb, yb, zb, xb2, yb2, zb2, xa2, ya2, za2)
RGBcolor = 1
Call Z_четырехугольник(xb, yb, zb, xb2, yb2, zb2, xc2, yc2, zc2, xc, yc, zc)
RGBcolor = 8
Call Z_четырехугольник(xc2, yc2, zc2, xc, yc, zc, xd, yd, zd, xd2, yd2, zd2)
RGBcolor = 3
Call Z_четырехугольник(xa2, ya2, za2, xb2, yb2, zb2, xc2, yc2, zc2, xd2, yd2, zd2)
RGBcolor = 6
Call Z_четырехугольник(xd, yd, zd, xd2, yd2, zd2, xa2, ya2, za2, xa, ya, za)
RGBcolor = 14
Call Z_четырехугольник(xa1, ya1, za1, xb1, yb1, zb1, xc1, yc1, zc1, xd1, yd1, zd1)
RGBcolor = 18
Call Z_четырехугольник1(xa, ya, za, xa1, ya1, za1, xd1, yd1, zd1, xd, yd, zd)
RGBcolor = 19
Call Z_четырехугольник2(xd, yd, zd, xd1, yd1, zd1, xc1, yc1, zc1, xc, yc, zc)
RGBcolor = 20
Call Z_четырехугольник3(xa1, ya1, za1, xa, ya, za, xb, yb, zb, xb1, yb1, zb1)
RGBcolor = 5
Call Z_четырехугольник4(xc1, yc1, zc1, xb1, yb1, zb1, xb, yb, zb, xc, yc, zc)
RGBcolor = 2
End Sub
Пример функции рисования наклонной грани:
Sub Z_четырехугольник2(xa, ya, za, xb, yb, zb, _
xc, yc, zc, xd, yd, zd)
Xnabl = 200
Ynabl = 200
Znabl = 0
For x = xa To xd Step 1
For y = ya To ya - 10 Step -0.1
If y >= 40 - x And y >= x Then
z = (0 * x + 0.025 * y - 1) / (-0.00625) 'Функция плоскости
Call QQQ(x, y, z)
End If
Next y
Next x
End Sub
Sub QQQ(x, y, z)
Call XYZ(x, y, z, X_zbyf, Y_zbyf)
' определяем квадрат расстояние от рассматриваемой точки до наблюдателя
Rnabl = ((Xnabl - x) ^ 2 + (Ynabl - y) ^ 2 + (Znabl - z) ^ 2) ^ 0.5
' извлекаем данные о значении координаты Y в Z буфере
Zbyf = Worksheets("zbyf").Cells(Y_
' если новое значение ближе к наблюдателю то заменняем значение в
' z буфере и в буфере кадра
If Rnabl < Zbyf Then
Worksheets("zbyf").Cells(Y_
Worksheets("кадр").Cells(Y_
End If
End Sub
Сканируем каждый пиксель каждой грани трехмерной фигуры.
Для граней организуем 2 два цикла по осям ox и oy или oz, по оси оу или oz вводим ограничения прямыми, проекциями отрезков ребер наклонной грани на плоскости. Значения оставшейся координаты будем вычислять из функции плоскости.
ax+by+cz+d=0
Определяем координаты данной точки на листах «экран» «кадр» и «zbyf». Естественно, что вся информация о пикселах на экране храниться в ячейках с тем же именем на листах «кадр» и «zbyf».
Call XYZ(x, y, za, X_zbyf, Y_zbyf)
Определяем расстояние от рассматриваемой точки до наблюдателя.
Rnabl = ((Xnabl - x) ^ 2 + (Ynabl - y) ^ 2 + (Znabl - z) ^ 2) ^ 0.5
Извлекаем данные о значении расстояния до наблюдателя точки с координатами X_zbyf, Y_zbyf в Z буфере. Напомни, что на первых шагах, извлекаемые значения Zbyf=1000.
Zbyf = Worksheets("zbyf").Cells(Y_zby
Производим сравнение, если новое значение Rnabl меньше, чем значение в z буфере, значит данная точка ближе к наблюдателю и закрывает от него предыдущую. Новое значение переменной Rnabl заносим на лист «zbyf».
If Rnabl < Zbyf Then
Worksheets("zbyf").Cells(Y_
Одновременно с изменением значения свойств пиксела на листе «zbyf» происходит изменение и на листе "кадр". В данном случае на этот лист заноситься значение индекса цвета грани параллелепипеда. Вид данного листа приведено ниже.
Worksheets("кадр").Cells(Y_
End If
Next x
Next y
Лист zbyf
Лист экран

- Компьютерная графика
- Компьютерная графика
- Компьютерная графика
- Компьютерная графика
- Компьютерная графика
- Компьютерная графика - 7 Вариант
- Компьютерная графика. Графические программы: Corel DRAW, Photoshop. Назначение, возможности, использование
- Компьютерная безопасность
- Компьютерная безопасность
- Компьютерная безопасность
- Компьютерная безопасность (1)
- Компьютерная вирусология
- Компьютерная грамотность и пути ее формирования
- Компьютерная графика