Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> классы/примеры программ для работы с 3d, (отображения 3d примитивов) без directx 
V
    Опции темы
gfmail
Дата 7.9.2007, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 8.7.2006

Репутация: нет
Всего: нет



Задача стоит такая: нарисовать 3d примитив(например куб), без использование directx, opengl и подобных. В принципе, часть этого уже реализована(куб рисуется и вращется), но сделать удаление скрытых линий(или закраску), не могу уже почти неделю. Искал много где, но везде или код без удаления невидимых линий, или алгоритм их удаления. Может кто-то реализовывал этот алгоритм? Пожалуйста, подскажите, где можно найти пример кода на С#(желательно).
PM MAIL ICQ   Вверх
mr.DUDA
Дата 9.9.2007, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Могу посоветовать следующее, пока без примера (т.к. ваших функций отрисовки у меня нет): создаём массив флоатов NxN (по размеру области куда рисуем), изначально содержащий float.MaxValue. Далее, рисуя полигон, проверяем каждую точку полигона на значение в массиве по координатам точки на экране: если у точки полигона координата Z (в нашем случае это глубина) меньше или равна значению в массиве - значит точка видима. Иначе нет. Если точка оказывается видима, записываем в массив её глубину. И так далее.

В современной 3D-графике этот алгоритм реализован аппаратно и называется z-buffer (или w-buffer, в случае float-формата). Программная эмуляция будет тормозить, т.к. нужно вручную отрисовывать каждую точку полигона.

Другой вариант -- сортировка полигонов, так чтобы перекрывающиеся более дальние полигоны отрисовывать первыми. Нетривиальная задача, с ходу идей нет.




--------------------
user posted image
PM MAIL WWW   Вверх
gfmail
Дата 9.9.2007, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 8.7.2006

Репутация: нет
Всего: нет



Проблема в том, что рисую я не отдельно каждую точку, а линиями рисую каркас. 
Вот код проецирования координат на экран. (в данном случае - фигура это 3д буква с 16 углами)

Код

 for (int i = 0; i < 16; i++)
            {
                a = dx[i] / (xSize / 2);
                b = dy[i] / (ySize / 2);
                c = (dz[i] + dist) / dist;

                x[i] = (int)(xSize/2 + xSize/2 * a/c);
                y[i] = (int)(ySize / 2 - ySize / 2 * b / c);
            }


После этого фигура рисуется соединияя линиями спроецированные точки.(думаю из-за этого алгоритма прорисовки не могу прикрутить удаление невидимых линий, но как сделать по-другому не знаю).

Код

 using (System.Drawing.Graphics g = offScreenDC)
            {
                for (int i = 0; i < 7; i++)
                {
                    g.DrawLine(linePen, new Point((int)x[i] + Xoffset, (int)y[i] + Yoffset), new Point((int)x[i + 1] + Xoffset, (int)y[i           + 1] + Yoffset));
                    g.DrawLine(linePen, new Point((int)x[i + 8] + Xoffset, (int)y[i + 8] + Yoffset), new Point((int)x[i + 9] + Xoffset, (int)y[i + 9] + Yoffset));

                }
                g.DrawLine(linePen, new Point((int)x[0] + Xoffset, (int)y[0] + Yoffset), new Point((int)x[7] + Xoffset, (int)y[7] + Yoffset));
                g.DrawLine(linePen, new Point((int)x[8] + Xoffset, (int)y[8] + Yoffset), new Point((int)x[15] + Xoffset, (int)y[15] + Yoffset));

                for (int i = 0; i < 8; i++)
                {
                    g.DrawLine(linePen, new Point((int)x[i] + Xoffset, (int)y[i] + Yoffset), new Point((int)x[i + 8] + Xoffset, (int)y[i + 8] + Yoffset));
                }
            }

            e.Graphics.DrawImage(offScreenBmp, 0, 0);

PM MAIL ICQ   Вверх
mr.DUDA
Дата 10.9.2007, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Если рисуется по линиям - помочь не могу.


--------------------
user posted image
PM MAIL WWW   Вверх
gfmail
Дата 11.9.2007, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 8.7.2006

Репутация: нет
Всего: нет



Да алгоритм прорисовки не важен, если знаете другой, такой же простой, то подскажите пожалуйста. Я пробовал рисовать плоскостями(по спроецированным координатам, с помощью FillPolygon), вроде неплохо получается, но по какому принципе эти плоскости сортировать по приоритету прорисовки? Сравнивать по центральное точке плоскости?
PM MAIL ICQ   Вверх
mr.DUDA
Дата 11.9.2007, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Алгоритм важен. Если бы рисовали по пикселам, реализация была бы тривиальная. По плоскостям - можно сортировать по ближайшей точке (но тогда не учитываются пересечения полигонов, если они есть). По линиям - вообще не в курсе, но даже на zx-спектруме был какой-то алгоритм в своё время, так что в гугле можно попробовать поискать по hidden line removal.


--------------------
user posted image
PM MAIL WWW   Вверх
gfmail
Дата 11.9.2007, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 8.7.2006

Репутация: нет
Всего: нет



Алгоритм важен, я имел ввиду что мне не важно каким алгоритмом рисовать, т.е. я бы мог и по точкам рисовать. А вот сортировать по ближайшей точке это то, что нужно, пока не пробовал, но кажется, это подойдет, т.к. пересечений  не планируется. Большое спасибо за ответы smile .
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0691 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.