![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() |
18192123 |
![]()
Сообщение
#1
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Мне нужно изобразить тетраэдр , выполнить закраску Фонга относительно выбранного источника света, разработать процедуру управления скоростью вращения тела с одинаковыми ускорениями по осям и обеспечения перехода на низкозатратную процедуру Гуро и далее на закраску с использованием таблиц освещенности при увеличении угловых скоростей вращения.
Вот... Не знаю даже, с чего начать... Теорию по методам закраски изучила.... но с таким никогда не сталкивалась, поэтому с реализацией большие проблемы.... вот на что думаю опираться: 1. Получить нормаль грани: выбрать два вектора, лежащие в этой грани и найти их векторное произведение, нормировать этот вектор. 2. Записать найденные нормали граней в массив (normg[i]). Чтобы определить нормаль каждой вершины, определяем из таблицы граней для каждой вершины, какие грани в ней сходятся, и для этих найденных граней их нормали суммируем, а сумму нор-мируем (массив normv[i]). 3. Алгоритм Гуро. После того, как нормали вершин найдены, вы-числяем согласно модели освещения освещенность каждой вершины и записываем освещенности в массив освещенностей. Этот массив будет использоваться в процедуре рисования грани. Алгоритм Фонга. Координаты найденных нормалей вершин пе-реводятся в сферические координаты, так что нормали представле-ны двумя числами типа byte. Нормали в таком виде будут использо-ваны процедурой рисования грани. 4. Реализовать процедуру рисования грани, для чего необходимо провести интерполяцию для определения освещенности (в ме-тоде Гуро) и нормали (в методе Фонга) для каждой точки гра-ни. Закраску граней можно произвести путем заполнения внутренней области этой грани отрезками прямых, параллельных оси OX. Для этого найдем вершины грани с наименьшей и наибольшей координатой Y. В качестве начальной возьмем вершину с наименьшей координатой Y. Разобьем условно множество ребер, составляющих грань, на две группы – левую и правую. Будем по очереди брать одно ребро из левой и одно из правой части, т.е. всегда работать с парой ребер. Выбор ребер может производиться следующим образом: сначала берем в качестве левого ребра ребро, начинающееся в начальной вершине и заканчиваю-щееся в следующей по порядку при обходе влево. Это ребро (l0,lk). Аналогично, в качестве первого правого ребра – ребро (r0,rk). Теперь в цикле будем строить прямые, параллельные оси X, начиная с прямой Y = Ymin, каждый раз увеличивая ординату. Для каждой этой прямой бу-дем находить точки пересечения с нашей парой боковых ребер. Если одно из боковых ребер не имеет точки пересечения с этой прямой, то его отбрасываем и берем следующее из его группы (левой или правой). Если точки пересечения найдены, то найдем, какая часть левого и правого ребра пройдена, это значение запишется соответственно в пе-ременные tl и tr. Значение переменных tl и tr используется на первом шаге билинейной интерполяции в методе Гуро для нахождения осве-щенности в точках пересечения прямой, параллельной оси Х, и ребер, а в методе Фонга для определения нормалей тела в этих точках. Второй шаг интерполяции ведется аналогично, только вдоль отрезка, заключен-ного между парой ребер. Таким образом, вычисляется необходимая ин-формация для каждой точки грани. но как всё это реализовать - не знаю! С чего начинать! Может быть кто-нибудь может привести реализацию методов закраски? |
![]() ![]() |
18192123 |
![]()
Сообщение
#2
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
и что значит "нормировать" вектор? ( как это производится?)
|
Malice |
![]()
Сообщение
#3
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 705 Пол: Мужской Репутация: ![]() ![]() ![]() |
Вот еще с далеких фидошных времен откопался примерчик заливки по фонгу, думаю поможет:
![]() |
18192123 |
![]()
Сообщение
#4
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Вот еще с далеких фидошных времен откопался примерчик заливки по фонгу, думаю поможет: ![]() Спасибо! Но лучше уж я с чистого листа начну.... Вопросы из сообщений 8 и 9 до сих пор для меня не ясны... |
18192123 |
![]()
Сообщение
#5
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Спасибо! Но лучше уж я с чистого листа начну.... Вопросы из сообщений 8 и 9 до сих пор для меня не ясны... Почему никто не хочет мне этого объяснить на моём примере? Я хочу сделать сама, но мне нужно вначале понять, как начинать, а начинать нужно с взятия нормалей, нахождения их векторного произведения и нормирования полученного вектора.... Ну не пойму я, как выбрать в начале вектора! ( а в программе, которую оставил Malice для меня всё не понятно! Да и объёмчик внушительный!) |
Сергей |
![]()
Сообщение
#6
|
Гость ![]() |
Почему никто не хочет мне этого объяснить на моём примере? Я хочу сделать сама, но мне нужно вначале понять, как начинать, а начинать нужно с взятия нормалей, нахождения их векторного произведения и нормирования полученного вектора.... Ну не пойму я, как выбрать в начале вектора! ( а в программе, которую оставил Malice для меня всё не понятно! Да и объёмчик внушительный!) Сейчас я всё попробую объяснить на конкретном примере=) Для начала я бы модифицировал сам пример для большего удобства работы. Вообще я писал бы на объектах=), но не всё сразу. Во первых описал бы типы: Код type TPoint3d = record {Трёхмерная точка} case byte of 0: (x, y, z: real); {заданная либо тремя координатами в отдельных полях записи} 1: (v: array[0..2] of real); {либо тремя элементами массива. Тогда 0й-x, 1й-y...} end; TNumLine = array[0..1] of integer; {тип, хранящий пару номеров вершин одного ребра} TNumPlane = array[0..2] of integer; {тип, хранящий тройку номеров вершин одной грани} TTetra = record {Тип, описывающий тетраэдр} Points: array[0..3] of TPoint3d; {Все четыре вершины тетраэдра} Edges: array[0..5] of TNumLine; {Все шесть ребер тетраэдра, заданные парами номеров соединяемых ребрами вершин из массива Points} Planes: array[0..3] of TNumPlane; {Все четыре треугольных грани тетраэдра. Каждая грань задана тройкой номеров вершин, входящих в неё. Номера вершин в соответствии с массивом Points.} end; тогда наш тетраэдр будет задан следующей типизованной константой: Код const Tetra: TTetra = ( Points: ( {Все точки тетраэдра} (X: -1; Y: -1; Z: -1), {0} (X: -1; Y: -1; Z: 1), {1} (X: -1; Y: 1; Z: -1), {2} (X: -1; Y: 1; Z: 1));{3} Edges: ( {Все рёбра тетраэдра} (0, 1), (0, 2), (0, 3), (1, 2), (2, 3), (3, 1)); Planes: ( {Все грани тетраэдра} (0, 1, 2), {внимание! грани лучше задавать так, чтобы если смотреть на них} (0, 2, 3), {снаружи, то точки обхода грани шли против часовой стрелки} (0, 3, 1), {зачем это надо скажу ниже} (1, 2, 3)) ); Тепрь бы я написал функции перевода координат из трёхмерных в экранные. По-хорошему это надо делать с помощью афинных преобразований, но для начала сойдёт и выкорчевывание кода из привелённой выше по форуму программки. Я обещал рассказать зачем надо обходить грани против часовой стрелки. По порядку. Грань -- это плоскость. Она задана тремя точками не лежащими на одной прямой. К любой плоскости можно построить нормаль. Любая точка -- это вектор. Положим все знакомы с операциями сложения/вычитания векторов, а также с операцией их векторного умножения. Итак, плоскость задана тремя точками (векторами) a, b и c. У нашего тетраэдра грани имеют две стороны: лицевую и изнаночную. Положим точки a, b и c, если смотреть на грань с лицевой стороны расположены так, что двигаясь от a к b, от b к c и от c к a мы двигаемся против часовой стрелки. Получаем два вектора: (ab)=b-a и (ac)=c-a. Векторное произведение v=(ab)*(ac) -- это вектор, перпендикулярный плоскости (abc). Прчем по правилу буравчика он будет смотреть из плоскости в нашу сторону, то есть в сторону лицевой стороны. Если нормировать этот вектор n=v/|v|, то получим как раз нормаль к плоскости abc. Кстати, я не проверял координаты точек, которыми задан тетраэдр. Очень может быть, что они как раз не удовлетворяют требованию обхода против часовой стрелки. Я полагал, что нулевая точка тетраэдра -- это его вершина, а три другие в основании. Так что нужно проверить, чтобы это было именно так. Для первого раза хватит? Потом дальше расскажу, если всё ещё интересно=). P.S. Я приношу свои извинения, если ошибся в синтаксисе. Писал прямо в браузере, и мог опечататься. К тому же сто лет не открывал Турбо Паскаля. |
![]() ![]() |
![]() |
Текстовая версия | 20.07.2025 6:44 |