Иллюстрированный самоучитель по Visual Studio.Net


Строим икосаэдр - часть 2


Величина его равна площади параллелограмма, построенного на векторах а и b как на сторонах, а направление определяется так, что векторы a, b и п образуют правую тройку. Последнее означает, что если представить наблюдателя на конце вектора п, то он видит поворот вектора а к вектору b, совершаемый по кратчайшему пути против часовой стрелки. На рис. 6.4. изображена нормаль п (правая тройка) при различной ориентации перемножаемых векторов а и b.

Рис. 6.2. Ориентация вектора нормали

Если координаты векторов а и b известны, то координаты нормали вычисляю по следующим формулам. Длина вектора нормали п зависит от длин вектор сомножителей и величины угла между ними:

Nx=AxBz-AzBy

Ny=AzBx-AxBz

Nz=AxBy-AyBx

Примечание

Можно потерять много времени на осознание того факта, что не только правление нормали, но и ее модуль влияют на величину освещенности (и та) вершины, так как сопровождающая документация (Help) не содер; явных указаний на это. Отметьте также, что цвета вершин полигона влияю цвета точек заполнения полигона, так как цвета вновь генерируемых то интерполируются, то есть принимают промежуточные значения между з чениями цвета вершин.

Чтобы нивелировать зависимость цвета вершины от амплитуды нормали, обыч вектор нормали масштабируют (или нормируют), то есть делают его длину р; ной единице, оставляя неизменным направление. С учетом сказанного создал две вспомогательные функции. Первая масштабирует, а вторая вычисляет н< маль к плоскости треугольника. Алгоритм вычисления использует координа двух сторон, прилегающих к текущей вершине треугольника:

//====Нормирование вектора нормали (или любого другого)

void Scale(double v[3])

{

double d = sqrt(v[0]*v[0]+v[l]*v[l]+v[2]*v[2]);

if (d == 0.)

{

MessageBox(0,"Zero length vector","Error",MB_OK);

return;

}

void getNorm(double vl[3], double v2[3], double out[3])

{

//===== Вычисляем координаты вектора нормали

//====== по формулам векторного произведения

out[0] = vl[l]*v2[2] - vl[2]*v2[l];




Начало  Назад  Вперед