Автор: Пользователь скрыл имя, 02 Апреля 2012 в 11:32, контрольная работа
Компьютерная графика, решение алгоритмов.
Алгоритм №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)