Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 25.07.2016
Сообщений: 21
1

Рисование нормалей в геометрической фигуре (икосаэдр)

14.03.2018, 21:08. Показов 1881. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть код, рисующий икосаэдр путем создания отдельных треугольников с 3мя типами нормалей:
"жесткой" (DrawTriaFlat - для вычисления нормали используется векторное произведение и производится с помощью вспомогательных функций )
и "мягкой" (DrawTriaSmooth - нормали находятся в вершинах треугольника )
есть заготовка в виде функции DrawNorm, которая должна рисовать нормали этих 2х типов, примерно это должно выглядеть, как на рисунках.
Не могу понять, как это осуществить.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#include "stdafx.h"
 
float
    rotX, rotY,
    dx, dy, dz = -4,
    r = (1 + sqrt(5)) / 2, // Золотое сечение
    v[12][3] =      // 12 вершин (x,y,z)
    {
        0, 1, r,  0,-1, r,  0, 1,-r,  0,-1,-r,
        1, r, 0, -1, r, 0,  1,-r, 0, -1,-r, 0,
        r, 0, 1, -r, 0, 1,  r, 0,-1, -r, 0,-1
    },
    rotMat[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
    color[] = { 0.1f, 0.6f, 0.1f },
    colorNorm[] = { 0.1f, 0, 0.1f };
 
int id[20][3] = // 20 triangular faces (порядок рисования граней против часовой стрелки, если смотреть со стороны оси z)
    {
        0, 1, 8,   0, 9, 1,   0, 8, 4,   0, 4, 5,   0, 5, 9,
        2, 3, 11,  2, 11, 5,  2, 5, 4,   2, 4, 10,  2, 10, 3,
        1, 9, 7,   1, 7, 6,   1, 6, 8,   3, 10, 6,  3, 6, 7,
        3, 7, 11,  4, 8, 10,  5, 11, 9,  6, 10, 8,  7, 9, 11
    };
 
short posX, posY;
bool leftButton, flat, growing = true, scaled;
int depth;
 
void AddRot(float a, int x, int y, int z)
{
    glPushMatrix();
    glLoadIdentity();
    glRotatef(a, x, y, z);
    glMultMatrixf(rotMat);
    glGetFloatv(GL_MODELVIEW_MATRIX, rotMat);
    glPopMatrix();
}
 
void OnPaint()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);     // Будем пользоваться услугами MM
    glLoadIdentity();
 
    glTranslatef(dx, dy, dz); // Смещение координат точек будущих примитивов
    glMultMatrixf(rotMat);
    glCallList(1);
    
    glutSwapBuffers();
 
}
 
void DrawNorm(float* n, float* a)
{
    glColor3fv(colorNorm);
    glBegin(GL_LINES);
    glVertex3fv(a);
    glVertex3fv(n);
    glEnd();
}
 
void DrawTriaSmooth(float* v1, float* v2, float* v3)
{
    glColor3fv(color);
    glBegin(GL_TRIANGLES);
    glNormal3fv(v1);        glVertex3fv(v1); 
    glNormal3fv(v2);        glVertex3fv(v2);
    glNormal3fv(v3);        glVertex3fv(v3);
    glEnd();
}
 
void ToUnit(float v[3]) // Нормируем вектор
{
    float d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
    if (d == 0)
    {
        MessageBox(0, "Zero length vector", "Error", MB_OK);
        return;
    }
    v[0] /= d; v[1] /= d; v[2] /= d;
}
 
void GetNorm(float a[3], float b[3], float n[3])
{
    // Вычисляем координаты вектора нормали по формулам векторного произведения
    n[0] = a[1] * b[2] - a[2] * b[1];
    n[1] = a[2] * b[0] - a[0] * b[2];
    n[2] = a[0] * b[1] - a[1] * b[0];
    ToUnit(n);
}
 
void DrawTriaFlat(float* v1, float* v2, float* v3)
{
    float norm[3], a[3], b[3];
    for (int i = 0; i < 3; i++) // Векторы a и b – это стороны треугольника
    {
        a[i] = v3[i] - v2[i];
        b[i] = v1[i] - v2[i];
    }
    GetNorm(a, b, norm);    // Вычисляем нормаль и создаем треугольник   
    DrawNorm(norm, v1);
    glColor3fv(color);
    glBegin(GL_TRIANGLES);
    glNormal3fv(norm);  
    glVertex3fv(v1);
    glVertex3fv(v2);
    glVertex3fv(v3);    
    glEnd();
}
 
void DrawScene()
{
    glNewList(1, GL_COMPILE);
    for (int i = 0; i < 20; i++)
        DrawTriaFlat(v[id[i][0]], v[id[i][1]], v[id[i][2]]);
    glEndList();
}
 
 
void OnSize(int w, int h)   // Реакция на WM_SIZE
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, double(w) / h, 1, 100);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
 
}
 
void OnKey(byte ch, int x, int y)
{
    switch (ch)
    {
    case 27: exit(0); break;
 
    case 'c': break;
    case '2': break;    
    }
    glutPostRedisplay();
}
 
void OnSpecialKey(int key, int x, int y)
{
    switch (key)
    {
    case GLUT_KEY_LEFT: dx -= 0.1; break;
    case GLUT_KEY_RIGHT: dx += 0.1; break;
    case GLUT_KEY_DOWN: dy -= 0.1; break;
    case GLUT_KEY_UP:  dy += 0.1; break;
    }   
    glutPostRedisplay();
}
 
void OnIdle()
{
    AddRot(rotX / 120, 0, 1, 0);
    AddRot(rotY / 120, 1, 0, 0);
    glutPostRedisplay();
}
 
void OnMouse(int button, int state, int x, int y)
{
    leftButton = button == GLUT_LEFT_BUTTON;
    if (state == GLUT_DOWN)
    {
        rotX = 0;
        rotY = 0;
        glutIdleFunc(0);
    }
    else
    {
        if (fabs(rotX) > 2 || fabs(rotY) > 2)
            glutIdleFunc(OnIdle);
    }
    posX = x;   // Запоминаем координаты мыши
    posY = y;
}
 
void OnMouseMove(int x, int y)
{
    rotX = (x - posX);
 
    rotY = (y - posY);
 
    if (leftButton)
    {
        AddRot(rotX / 10, 0, 1, 0);
        AddRot(rotY / 10, 1, 0, 0);
    }
    else
    {
        dz += (x - posX + y - posY) / 50.0f;// Вычислите степень удаления или приближения и измените величину dz пропорционально смещению мыши
    }
    posX = x;   // Запоминаем новые координаты мыши
    posY = y;
    glutPostRedisplay();
}
 
void Init() // Настройки
{
    glClearColor(1, 1, 1, 0);   // Цвет фона - белый   
    glEnable(GL_DEPTH_TEST);    //учет глубины
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // GL_FILL - полная заливка всех граней   
    glEnable(GL_LIGHT0); //добавление освещения
    glEnable(GL_LIGHTING); //включение освещения
    glEnable(GL_COLOR_MATERIAL); //включить "учитывать цвет материала"
    glEnable(GL_CULL_FACE);
    DrawScene();
}
 
void main()
{
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(700, 500);
    glutCreateWindow("Icosahedron");
 
    Init();
 
    glutMouseFunc(OnMouse);
    glutMotionFunc(OnMouseMove);
    glutSpecialFunc(OnSpecialKey);
    glutKeyboardFunc(OnKey);
    glutReshapeFunc(OnSize);
    glutDisplayFunc(OnPaint);
    glutMainLoop();
    
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.03.2018, 21:08
Ответы с готовыми решениями:

Определить принадлежность точки геометрической фигуре
Разработать алгоритм и программу на одном из алгоритмических языков, чтобы определить...

Определить, принадлежит ли точка с координатами геометрической фигуре
Не могу понять, как составить программу к задаче: Даны действительные числа х,у. Определить,...

Как задать произвольный размер ( с клавиатуры) простой геометрической фигуре
Нужно, задать размер фигуры например круга или квадрата, но с клавиатуры. Программа будет...

Рисование геометрической фигуры С(Си)
# include&lt;stdio.h&gt; int main() { int n=10, i,j; //C for (i=0; i&lt;n; i++) ...

3
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
16.03.2018, 21:18 2
Цитата Сообщение от Ariel_123 Посмотреть сообщение
Не могу понять, как это осуществить.
“посчитать вертексные нормали как сумму нормалей всех фейсов использующих этот вертекс.”
https://www.cyberforum.ru/post9539514.html

Фигура симметричная, наверно вертексные это направление из центра фигуры к вершинам.
0
1824 / 732 / 99
Регистрация: 01.10.2012
Сообщений: 3,748
18.03.2018, 08:21 3
Цитата Сообщение от Excalibur921 Посмотреть сообщение
“посчитать вертексные нормали как сумму нормалей всех фейсов использующих этот вертекс.”
Подзабыл кто такой икосаэдр, но может просто посчитать для него средние нормали как для сферы? (т.е. просто нормируя вертекс в модельных координатах)
0
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
18.03.2018, 11:15 4
Цитата Сообщение от Igor3D Посмотреть сообщение
нормируя вертекс в модельных координатах
Ну вот же тоже самое:
Цитата Сообщение от Excalibur921 Посмотреть сообщение
наверно вертексные это направление из центра фигуры к вершинам.
0
18.03.2018, 11:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.03.2018, 11:15
Помогаю со студенческими работами здесь

Рисование любой плоской геометрической фигуры
Язык Java предоставляет средства для поддержки технологии WYSIWYG и GUI. Средства, связанные с GUI,...

Рисование геометрической фигуры используя собственные классы.
Здравствуйте. Есть такое задание : Заданная геометрическая фигура рисуется в форме, положение и...

Тетраэдр Гексаэдр Октаэдр Додекаэдр Икосаэдр
Тетраэдр Гексаэдр Октаэдр Додекаэдр Икосаэдр Как все это выглядит в координатах?

Сменить икосаэдр на додекаэдр при клике мышью
Ребят нужна помощь. Нужно реализовать функцию что бы при клике мышью икосаэдр менялся на додекаэдр....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru