ВНИМАНИЕ! Наша конференция посвящена космической тематике и компьютерным играм. Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!
|
» Псевдослучайная генерация, - панацея или химера? | страница 4 |
|
|
|
Канал Игры Мечты: «Псевдослучайная генерация, - панацея или химера?» |
|
|
Криптон
1011 EGP
       Рейтинг канала: 3(44) Репутация: 164 Сообщения: 2667 Откуда: Москва Зарегистрирован: 05.04.2008
 |
|
Вот только сейчас обратил внимание:
Код: |
void MakeCurve ( float XYCurve [360][2] )
{
float PolCurve [360]; // тут хранится 360 штук значений радиус-вектора, а номер элемента массива - угол его поворота в градусах.
int i;
for (i = 1; i<360; i++)//ОЧЕВИДНО, ТУТ i - ГРАДУСЫ
{ //printf ("%d \n", i);
PolCurve [i] = SuperFormula (i, 3,1,3,5,18,18); // считаем суперформулу для угла i, и записываем результат (дл. рад-вект.) в элемент массива.
XYCurve [i][1] = PolCurve [i] * cos(rad2deg(i));//А ТУТ i УЖЕ РАДИАНЫ // пересчитываем икс-координату из полярной формы в декартову.
XYCurve [i][2] = PolCurve [i] * sin(rad2deg(i)); // то же самое для игрек-координаты.
}
} |
мои большие буквы - чтоб в глаза бросалось.
добавлено спустя 6 минут:
К тому же, если я не ошибаюсь, функции cos() и sin() требуют именно что радианов в качестве аргумента
Последний раз редактировалось: Криптон (23:34 01-12-2008), всего редактировалось 1 раз |
|
|
Jerry Rezet
581 EGP
  Рейтинг канала: 5(113) Репутация: 86 Сообщения: 3365 Откуда: Санкт-Петербург. Зарегистрирован: 01.04.2005
 |
|
*бъёццо галавой ап стену* *WALL*
Ип..понцкий городовой.. Тьху.. тогда не cos(rad2deg(i) а cos(deg2rad(i).. Тупарь..
Криптон - спасибо! Сча попробую..
добавлено спустя 4 минуты:
Блин.. Это действительно было той самой ошибкой, которая всё меняет, но при исправлении получается, что рисуется просто ровный круг. Значит накосячил где-то с объявлением и инициализацией переменных. Потому что весь массив забит единицами, походу.
Пошёл проверять инициализацию.
добавлено спустя 10 минут:
Да.. Я был прав.. Хрень какая-то..
Код: |
void MakeCurve ()
{
float PolCurve [360];
int i;
for (i = 1; i<360; i++)
{
PolCurve [i] = SuperFormula ( deg2rad(i), 3,1,3,5,18,18);
printf ("%d : %f \n", i, PolCurve [i]);
XYCurve [i][1] = PolCurve [i] * cos(deg2rad(i));
XYCurve [i][2] = PolCurve [i] * sin(deg2rad(i));
}
} |
Контрольная распечатка printf ("%d : %f \n", i, PolCurve [i]); показывает, что массив забит сплошными единицами.. Никак немугу понять, где я так облажался..
_________________ - Вы не представляете, как вам повезло, что я здесь. Вы об этом еще пожалеете. [c]
Последний раз редактировалось: Jerry Rezet (23:57 01-12-2008), всего редактировалось 2 раз(а) |
|
|
Криптон
1011 EGP
       Рейтинг канала: 3(44) Репутация: 164 Сообщения: 2667 Откуда: Москва Зарегистрирован: 05.04.2008
 |
|
быстренько слепил программку. С теми параметрами, что в сообщениях, только диапазон углов сменил с 1..360 на 1..720, получилось:
Cкрытый текст (кликните здесь для просмотра)
|
Оно?
добавлено спустя 5 минут:
Jerry Rezet : |
PolCurve [i] = SuperFormula ( deg2rad(i), 3,1,3,5,18,18);
|
А в SuperFormula преобразования из градусов в радианы больше нет, надеюсь? Если нет, то не в курсе причины проблемы - "перевод" на delphi работает нормально.
Последний раз редактировалось: Криптон (00:12 02-12-2008), всего редактировалось 1 раз |
|
|
Jerry Rezet
581 EGP
  Рейтинг канала: 5(113) Репутация: 86 Сообщения: 3365 Откуда: Санкт-Петербург. Зарегистрирован: 01.04.2005
 |
|
Оно..
По крайней мере более похоже.. с утреца или завтра вечерком проверю.. А то голова уже под ночь квадратная. Плиз, скинь в личку лист проги Если невлом..
_________________ - Вы не представляете, как вам повезло, что я здесь. Вы об этом еще пожалеете. [c] |
|
|
Криптон
1011 EGP
       Рейтинг канала: 3(44) Репутация: 164 Сообщения: 2667 Откуда: Москва Зарегистрирован: 05.04.2008
 |
|
Я могу и здесь выложить:
Cкрытый текст (кликните здесь для просмотра)
Код: |
unit UnMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, GLScene, GLObjects, GLMisc, GLWin32Viewer, Math;
type
TForm1 = class(TForm)
GLScene1: TGLScene;
GLSV: TGLSceneViewer;
GLCamera1: TGLCamera;
GLDummyCube1: TGLDummyCube;
GLL: TGLLines;
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function SuperFormula(alpha:double;a,b,m,n1,n2,n3:integer):double;
var
phi, r:single;
begin
phi := DegToRad(alpha); //переводим градусы в радианы
r := power(power(abs(cos(m*phi/4)/a), n2) + power(abs(sin(m*phi/4)/b), n3), -1/n1);
result:=r; //возвращаем длину радиус-вектора для угла phi (в радианах)
end;
procedure TForm1.FormShow(Sender: TObject);
var
PolCurve:array [1..720] of single; {тут хранится 720 штук значений радиус-вектора, а
номер элемента массива - угол его поворота в градусах. }
i:integer;
begin
for i := 1 to 720 do begin
PolCurve[i] := SuperFormula (i, 3,1,3,5,18,18); // считаем суперформулу для угла i, и записываем результат (дл. рад-вект.) в элемент массива.
with GLL.Nodes.Add do begin
X := 0.05*PolCurve [i] * cos(DegToRad(i)); // пересчитываем икс-координату из полярной формы в декартову.
Y := 0.05*PolCurve [i] * sin(DegToRad(i)); // то же самое для игрек-координаты.
z:=0;
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
GLSV.Free;
end;
end. |
UnMain.dfm (это чтоб было понятно, что я напихал на форму) (кликните здесь для просмотра)
Код: |
object Form1: TForm1
Left = 0
Top = 0
Width = 676
Height = 446
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnDestroy = FormDestroy
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object GLSV: TGLSceneViewer
Left = 0
Top = 0
Width = 668
Height = 417
Camera = GLCamera1
Buffer.BackgroundColor = clBlack
FieldOfView = 153.029327392578100000
Align = alClient
end
object GLScene1: TGLScene
Left = 432
Top = 88
object GLDummyCube1: TGLDummyCube
CubeSize = 1.000000000000000000
object GLL: TGLLines
Nodes = <>
NodesAspect = lnaInvisible
Options = []
end
end
object GLCamera1: TGLCamera
DepthOfView = 100.000000000000000000
FocalLength = 50.000000000000000000
TargetObject = GLDummyCube1
Position.Coordinates = {00000000CDCCCC3D000080400000803F}
end
end
end |
|
|
Написано на Delphi 2005 с установленной GLscene. Только я не в курсе, чем это может помочь - практически целиком алгоритмы позаимствованны из твоих постов.
Последний раз редактировалось: Криптон (00:43 02-12-2008), всего редактировалось 3 раз(а) |
|
|
Guest
2075 EGP
              Рейтинг канала: 5(167) Репутация: 376 Сообщения: 27975 Откуда: Моск. Зарегистрирован: 12.10.2004
 |
|
А можно вопрос, зачем нужно выделенное преобразование:
PolCurve [i] = SuperFormula ( deg2rad(i), 3,1,3,5,18,18);
?
В СуперФормуле и так идёт преобразование входного параметра с градусов в радианы.
_________________ Трещит земля как пустой орех
Как щепка трещит броня
Последний раз редактировалось: Guest (02:19 02-12-2008), всего редактировалось 1 раз |
|
|
Jerry Rezet
581 EGP
  Рейтинг канала: 5(113) Репутация: 86 Сообщения: 3365 Откуда: Санкт-Петербург. Зарегистрирован: 01.04.2005
 |
|
Гест, да, оно было нужно, когда "альфа" была в градусах. А в такой записи всё стало значительно проще - сразу задаём "фи", которая уже в радианах.:
Код: |
double SuperFormula (double phi, int a,int b, int m, int n1, int n2, int n3)
{ float r;
r = pow (pow(abs(cos(m*phi/4)/a), n2) + pow(abs(sin(m*phi/4)/b), n3), -1/n1);
return r;
} |
Типа так меньше кода. А раньше (в предыдущих моих листингах), - да, было преобразование в радианы из градусов внутри процедуры.
_________________ - Вы не представляете, как вам повезло, что я здесь. Вы об этом еще пожалеете. [c] |
|
|
Jerry Rezet
581 EGP
  Рейтинг канала: 5(113) Репутация: 86 Сообщения: 3365 Откуда: Санкт-Петербург. Зарегистрирован: 01.04.2005
 |
|
Так.. Я понял в чём трабла у мну была.. По крайней мере - частично..
В MSVC 6.0, да и вообще в сях модуль числа - int abs(int i); - от этого значения, меньше единицы округлялись до нуля - пришлось писать собственную функцию модуля.. Теперь, вот, контрольная распечатка выявила что степень - тоже как-то не так работает.. Блин.. Что там ещё "не так, как у людей"?
_________________ - Вы не представляете, как вам повезло, что я здесь. Вы об этом еще пожалеете. [c] |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Подозреваю, что всё
_________________ У меня бисера не доxеpа. |
|
|
Guest
2075 EGP
              Рейтинг канала: 5(167) Репутация: 376 Сообщения: 27975 Откуда: Моск. Зарегистрирован: 12.10.2004
 |
|
Jerry Rezet : |
степень - тоже как-то не так работает
|
Посмотри, правильно ли оно вычисляет квадратный корень - возможно, проблема в отрицательной степени
З.Ы.: жалко, поставить VS некуда, а то можно было бы воссоздать и посмотреть...
добавлено спустя 1 минуту:
Jerry Rezet : |
int abs(int i);
|
Эта... А там разве нет аналога для вещественных типов?
добавлено спустя 45 секунд:
У тебя ж дроби везде - всё должно быть во float'ах хотя бы...
_________________ Трещит земля как пустой орех
Как щепка трещит броня
Последний раз редактировалось: Guest (20:20 02-12-2008), всего редактировалось 2 раз(а) |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
Jerry Rezet : |
пришлось писать собственную функцию модуля..
|
неплохо, встречал конторы где предлагают на собеседовании заимплементить fabs() atoi() и прочие тривиальности
_________________ This is what you get ...
(c) Radiohead |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Степени и логарифмы тоже?
_________________ У меня бисера не доxеpа. |
|
|
Jerry Rezet
581 EGP
  Рейтинг канала: 5(113) Репутация: 86 Сообщения: 3365 Откуда: Санкт-Петербург. Зарегистрирован: 01.04.2005
 |
|
Ребят, я сам с себя ржу, когда натыкаюсь на такие вот баги даже не проги, а своего мышления, так что прошу вас - не добавляйте, ы? Я и так давно забыл, что такое "самолюбие" и прочая пофигень, ибо жутко мешает, но если Ширсон продолжит стебаться - я ж сдохну сосмеху
P.S.: Как отрицательные степени убрать - это математика школьная, но вот с дробными - у меня плохо. Пока что. Пока прогрессирует мой темпоральный кретинизм.
добавлено спустя 1 минуту:
Guest : |
А там разве нет аналога для вещественных типов?
|
Не нашёл. Но её-то написать проще, чем через числовые ряды считать корень n-ной степени.
_________________ - Вы не представляете, как вам повезло, что я здесь. Вы об этом еще пожалеете. [c]
Последний раз редактировалось: Jerry Rezet (22:09 02-12-2008), всего редактировалось 1 раз |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
Shirson : |
Степени и логарифмы тоже?
|
мну почудился сарказм, в игровом коде стараются выжать максимум, вот например тот же fabs, и для дельфи тож
т.н. bit twidding hacks
http://www.musicdsp.org/showone.php?id=132
_________________ This is what you get ...
(c) Radiohead |
|
|
Guest
2075 EGP
              Рейтинг канала: 5(167) Репутация: 376 Сообщения: 27975 Откуда: Моск. Зарегистрирован: 12.10.2004
 |
|
Sh.Tac. : |
т.н. bit twidding hacks
|
Да, очень порадовало обсуждение в комментариях
_________________ Трещит земля как пустой орех
Как щепка трещит броня |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Sh.Tac. : |
мну почудился сарказм, в игровом коде стараются выжать максимум
|
А реализация этих функций в языке такая медденная, что требуется её писать при приёме на работу?
Понятно, что понимание флагов и битовых операций можно проверить и так, но будет ли это действительно самый оптимальный код? (включая и устойчивость)
Цитата: |
вот например тот же fabs, и для дельфи тож
|
Насколько быстрее он работает по сравнению с библиотечной функцией? (хотя, это можно и проверить)
добавлено спустя 16 минут:
Код: |
procedure TForm1.Button1Click(Sender: TObject);
var
m:array of single;
a:longint;
tic1, tic2:longint;
sm:single;
function fastabs(f:single):single;
var i:longint;
begin i:=longint((@f)^) and $7FFFFFFF;result:=single((@i)^) end;
begin
randomize;
setlength(m,10000000);
for a:=0 to high(m) do
m[a]:=random*20-10;
sm:=0;
tic1:=GetTickCount;
for a:=0 to high(m) do
sm:=sm+abs(m[a]);
tic2:=GetTickCount;
form1.Caption:=floattostr(sm);
label1.Caption:=inttostr(tic2-tic1);
sm:=0;
tic1:=GetTickCount;
for a:=0 to high(m) do
sm:=sm+fastabs(m[a]);
tic2:=GetTickCount;
form1.Caption:=floattostr(sm);
label2.Caption:=inttostr(tic2-tic1);
end;
|
Последовательное взятие 10 000 000 раз функции.
Первый результат, библиотечная функция Delphi - 46-47 тиков.
Второй резульат, "fast" abs - 97-110 тиков.
В сад с таким выжиманием максимума
_________________ У меня бисера не доxеpа.
Последний раз редактировалось: Shirson (18:03 03-12-2008), всего редактировалось 3 раз(а) |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
Trident : |
Sh.Tac. : |
процедурная анимация
|
И ага. То есть теоретически она процедурная, а практически её делает аниматор. И если он чего не сделал, то ничего неспроцедурится.
|
вот тут заявляется, что честно симулируются мышцы и чуть ли не мозжечок
ролик забавный
_________________ This is what you get ...
(c) Radiohead |
|
|
AlexPin
51 EGP
 Репутация: 2 Сообщения: 21
Зарегистрирован: 14.06.2008
 |
|
Вот дошел, наконец, до решения написать свою игру. Конечно это будет космический симулятор. Основные принципы игры уже продуманы. Одним из кирпичиков будет случайная генерация игрового мира.
Я хотел бы обсудить предложенный мной способ генерации координат космических объектов. В качествеи критики хотелось бы услышать не просто фразы "этот способ фигня, я сделаю лучше", а конкретные способы как сделать лучше.
Для начала озадачился основными принципами генерации галактик. Как расположить космические объекты в галактике, чтобы они более или менее соответствовали реальным (или хотя бы походили на них), чтобы при генерации 2 или более космических объекта не попадали в одну точку?
Попробую рассказать к каким выводам я пришел:
Что представляет собой случайная генерация игрового мира?
Прежде всего это случайные координаты космических объектов (звездные системы, туманности, и т.д.) при начале новой игры. Как получить эти координаты, чтобы они были хотя бы похожими на реальные галактики? Для примера возьмем эллиптическую галактику (как наименее сложную).
Из каких "частей" состоит эллиптическая галактика?
Центр, ядро, все остальное.
Краткие характеристики частей галактики:
В центре располагается массивная черная дыра.
В ядре большая плотность звезд. Примем, что плотность эта одинакова по всему ядру. Ядро в форме шара с полостью в центре в виде тоже шара (в этой полости расположена черная дыра).
В оставшейся части галактики (в форме эллипса) чем дальше от центра, тем плотность звезд ниже.
На основе каких входных данных можно сгенерировать эллиптическую галактику?
1. В первую очередь - это размер (радиус_большой_полуоси эллипсоида)
2. Эксцентриситет (отношение радиуса большой полуоси эллипсоида к малой)
3. Относительная плотность звезд в генерируемой галактике.
Теперь определим основные параметры для генерации галактики:
1. На основании радиуса_большой_полуоси и эксцентриситета определим радиус_малой_полуоси.
2. Начальный_радиус_ядра примем за 0.01 от радиуса_малой_полуоси.
3. Конечный_радиус_ядра примем за 0.1 от радиуса_малой_полуоси.
4. "Разобьем" все пространство ядра на элементарные кубики, в объеме которых может с определенной вероятностью располагаться космический объект. Сторона_элементарного_куба в ядре зависит от требуемой относительной плотности космических объектов в галактике. Пусть
если плотность низкая, то сторона равна (размер_ядра)/5
если плотность средняя, то сторона равна (размер_ядра)/10
если плотность высокая, то сторона равна (размер_ядра)/20
6. Примем вероятность появления космического объекта в кубе в ядре 90%
7. И минимальное расстояние_космических_объектов_от_стенок_куба=(сторона_куба)/10
8. Сторона_элементарного_куба в остальной части зависит от требуемой относительной плотности космических объектов в галактике. Пусть
если плотность низкая, то сторона равна 5*(радиус_большой_полуоси-конечный_радиус_ядра)/радиус_большой_полуоси
если плотность средняя, то сторона равна (радиус_большой_полуоси-конечный_радиус_ядра)/(радиус_большой_полуоси*10)
если плотность высокая, то сторона равна (радиус_большой_полуоси-конечный_радиус_ядра)/(радиус_большой_полуоси*20)
9. Начальная_вероятность_появления_космических_объектов=90% (как в ядре)
10. Конечная_вероятность_появления_космических_объектов=40%
11. Минимальное расстояние_космических_объектов_от_стенок_куба=(сторона_куба)/10
Переходим непосредственно к процессу генерации. Процесс генерации координат космических объектов разбивается на несколько шагов:
1. Генерация черной дыры в центре.
2. Генерация координат в ядре.
3. Генерация координат в остальной части галактики.
Рассмотрим пункты 2 и 3.
2. Генерация координат в ядре:
Разбиваем положительные направления осей координат OX, OY, OZ на отрезки длиной, равной стороне куба в ядре (т.е. проверяем 1/8 част шара).
Проверяем каждый куб на полное попадание в объем ядра.
Если куб не попадает в этот объем, то проверяем следующий.
Если куб попадает в объем ядра, то
Для каждого из 8-ми кубов (по всем направлениям полуосей, а не только положительных) генерируем случайное число и, если оно меньше или равно параметру веростность, то генерируем случайные координаты для космического объекта на минимальном_расстоянии_от стенок.
Пункт 3 во много подобен 2. Отличия в том, что чем дальше от центра, тем меньше вероятность появления объекта в кубе (вероятность определяется по функции зависимости вероятности от расстояния от центра).
Генерация спиральной галактики несколько сложнее.
Все цифры - ориентировочные.
Хотелось бы услышать мнения по этому способу генерации. Может у кого-то есть более удобные или простые решения.
|
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
AlexPin : |
В ядре большая плотность звезд. Примем, что плотность эта одинакова по всему ядру. Ядро в форме шара с полостью в центре в виде тоже шара (в этой полости расположена черная дыра).
В оставшейся части галактики (в форме эллипса) чем дальше от центра, тем плотность звезд ниже.
|
позвольте спросить, а сколько звёзд планируется в галактике?
можно ли будет "потрогать" чёрную дыру?
Цитата: |
Конечно это будет космический симулятор.
|
какой направленности симулятор?
пока создаётся впечатление, что это очередной "симулятор" всего-всего-всего-на-свете...
каким образом игрок сможет увидеть всю галактику?
если только с борта своего космического кораблика ИМХО не стоит городить огород
_________________ This is what you get ...
(c) Radiohead |
|
|
AlexPin
51 EGP
 Репутация: 2 Сообщения: 21
Зарегистрирован: 14.06.2008
 |
|
Цитата: |
сколько звёзд планируется в галактике?
|
Количество звезд будет выбирать игрок при старте новой игры, опираясь на свое железо. Но мое мнение, что игровой мир должен быть как можно больше. А на вопрос о том, как будут обрабатываться столько объектов отвечу заранее, что обрабатываться они будут только если в них происходят какие-то игровые процессы. Неисследованные звездные системы будут просто храниться на диске. Начальное количество колонизированных систем невелико.
Цитата: |
какой направленности симулятор?
|
Похожие игры: Линейка Х, Фрилансер, Мастер Ориона. +стратегическая сторона в виде освоения новых систем, добычи в них ресурсов и т.д. Снигл с сюжетом. Короче, направление - "Игра мечты"
Цитата: |
"симулятор" всего-всего-всего-на-свете
|
Это не симулятор всего на свете. Идеи игры обдуманы. В них нет ничего сверхъестественного, но пока об этих идеях помолчу . Для изложения концепции, попозже, возможно, создам отдельную тему, а здесь хотелось бы услышать ваши мнения по конкретному вопросу (о таком способе генерации галактики).
Цитата: |
каким образом игрок сможет увидеть всю галактику?
|
На 3-мерной карте. Может, получится сгенерировать отображение звездного неба, соответствующего типу галактики и месту игрока в ней (не реальное расположение звезд, а просто имитацию, т.е., чем ближе к центру, тем больше точек на небе и т.п.).
Последний раз редактировалось: AlexPin (18:39 08-03-2009), всего редактировалось 2 раз(а) |
|
|
|
|
|
Канал Игры Мечты: «Псевдослучайная генерация, - панацея или химера?» |
|
К списку каналов | Наверх страницы |
Цитата не в тему: Я её вокальных параметров (грудь-талия-бёдра) не помню... (vetas)
|
» Псевдослучайная генерация, - панацея или химера? | страница 4 |
|