Страница: 1 |
Страница: 1 |
Вопрос: RND. Не очень-то он рандомен.
Добавлено: 02.11.05 23:56
Автор вопроса: Victor | Web-сайт:
Я тут пишу 3-хмерный движок. Пока он занимается только рисованием точек.
Так вот разглядывал я вот такой массив точек
For i = 0 To n - 1
Points(i).Pos.x = (Rnd - 0.5) * 0.1
Points(i).Pos.y = (Rnd - 0.5) * 0.1
Points(i).Pos.z = (Rnd - 0.5) * 0.1
Points(i).Color.rgbRed = Rnd * 255
Next i
И получил забавную картинку. Если на него (кубик) посмотреть с какой-то определенной стороны, получается следующее:
http://vt-dbnz.narod.ru/rnd.png
Забавно, правда?
Можно погучить решетку другой плотности, посмотрев еще с какой-нибудь другой стороны.
Примечание. Команда Randomize не вызывалась. Я не пробовал ее вызывать.
Ответы
Всего ответов: 14
Номер ответа: 1
Автор ответа:
vito
Разработчик Offline Client
Вопросов: 23
Ответов: 879
Web-сайт:
Профиль | | #1
Добавлено: 03.11.05 01:01
Есно дело, что он далек от идеала.
Если тебя интересуют генераторы псевдослучайных чисел, то добро пожаловать к классикам.
Д.Кнут "Исскуство программирования" Том 3. "Получисленные алгоритмы".
Номер ответа: 2
Автор ответа:
GSerg
Вопросов: 0
Ответов: 1876
Профиль | | #2
Добавлено: 03.11.05 02:01
http://bbs.vbstreets.ru/viewtopic.php?p=135910#135910
Номер ответа: 3
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #3
Добавлено: 03.11.05 11:36
http://vbnet.ru/forum/show.aspx?id=89390
Номер ответа: 4
Автор ответа:
Страшный Сон
Вопросов: 46
Ответов: 848
Профиль | | #4
Добавлено: 03.11.05 12:01
Есть такой метод генерации случайных чисел:
Private Function RandL() As Long
IRan = 1664525 * IRan + 1013904223
RandL = IRan
End Function
IRan - глобальная переменная. Генерируется при этом целое число. Не самый лучший, честно говоря, метод преобразования в Double выглядит так:
Private Function RandF() As Double
IRan = 1664525 * IRan + 1013904223
RandF = CDbl(IRan) / 4294967296# + 0.5
End Function
Private Function RandFN() As Double
IRan = 1664525 * IRan + 1013904223
RandFN = CDbl(IRan) / 4294967296#
End Function
Не забудь проверку на переполнения вырубить.
Номер ответа: 5
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #5
Добавлено: 04.11.05 10:11
Как раз полиномная (чаще всего использующаяся в стандартных ГСЧ) генерация случайных чисел и приводит к эффектам, вроде диагонального распределения плотности цвета.
Номер ответа: 6
Автор ответа:
Страшный Сон
Вопросов: 46
Ответов: 848
Профиль | | #6
Добавлено: 04.11.05 12:53
Но если вызвать Randomize, такие артефакты исчезают. На своем опыте убедился.
Номер ответа: 7
Автор ответа:
HACKER
Разработчик Offline Client
Вопросов: 236
Ответов: 8362
Профиль | | #7
Добавлено: 05.11.05 15:30
а откуда Rnd число генерирует, ну всмысле я так понимаю берётся что-то исходное (например дата и время), далее какой-то алгоритм который генерирует число исходя текущего времени... или я не прав?
Номер ответа: 8
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #8
Добавлено: 05.11.05 17:08
Rnd(base)
генератор случайных чисел обычно берет некое число seed, и base, начинает их жевать по определенному алгоритму и даёт на выходе псевдослучайное число. Один из промежуточных результатов работы генератора сохраняется как новое значение seed, чтобы при последующем обращении не получился тот же результат.
Первоначальная инициализация seed выполняется Randomize
Номер ответа: 9
Автор ответа:
HACKER
Разработчик Offline Client
Вопросов: 236
Ответов: 8362
Профиль | | #9
Добавлено: 05.11.05 22:23
а чё за это числа и откуда их берут?
Номер ответа: 10
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #10
Добавлено: 05.11.05 22:42
base - это число, которое является параметром функции Rnd. Т.е Rnd(12345) - это base=12345.
Seed - это переменная внутри того модуля (например msvbvm60), который считает случайное число, и которая хранит какое-то начальное значение. Оно меняется, когда вызываешь Randomize. Когда делают Randomize(GetTickCount), то seed устанавливается в некоторое достаточно случайное значение, зависящее от количества мсек, прошедших с момента включения компа. Потом на эту случайную величину наворачивается алгоритмом Rnd ещё другая "случайность", и в итоге получаем случайное число.
Сам алгоритм Rnd рано или поздно начнёт повторять последовательность своих выходных значений, а чтобы этого не происходило, и служит переменная seed. Её нужно почаще переставлять.
Номер ответа: 11
Автор ответа:
Victor
ICQ: 345743490
Вопросов: 42
Ответов: 385
Web-сайт:
Профиль | | #11
Добавлено: 06.11.05 00:13
Как однако вы меня просветили. Я знал, как применять функцию Randomize и Rnd(), чтобы получить какую-то определенную, довольно случайную последовательность.
Насколько я знаю, в качестве base берется последнее сгенерированное число. Кажется, в MSDN такое написано.
И еще спасибо за инфу о том, как сделать свой рандом-генератор.
Номер ответа: 12
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #12
Добавлено: 06.11.05 00:28
Насколько я знаю, в качестве base берется последнее сгенерированное число
base - это входной параметр функции, и последним сгенерированным он быть не может, ибо теряется весь смысл: на входе то же число, что и на выходе
Вот пример генератора случайных чисел из masmlib.
base - параметр на входе, внутренняя переменная seed (тут называется nrandom_seed) устанавливается на предпоследнем шаге алгоритма и сохраняется внутри
mov eax, nrandom_seed
; ****************************************
test eax, 80000000h
jz @F
add eax, 7fffffffh
@@:
; ****************************************
xor edx, edx
mov ecx, 127773
div ecx
mov ecx, eax
mov eax, 16807
mul edx
mov edx, ecx
mov ecx, eax
mov eax, 2836
mul edx
sub ecx, eax
xor edx, edx
mov eax, ecx
mov nrandom_seed, ecx
div base
mov eax, edx
ret
nrandom ENDP
Номер ответа: 13
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #13
Добавлено: 06.11.05 00:34
Вот кстати процедура установки seed (делает примерно то же, что и Randomize) Первоначально seed равен 12345678, и затем меняется либо непосредственным вызовом этой процедуры, либо при каждой генерации нового случайного числа предыдущей процедурой:
.data
nrandom_seed dd 12345678
.code
mov eax, TheSeed
mov nrandom_seed, eax
ret
nseed endp
Номер ответа: 14
Автор ответа:
HACKER
Разработчик Offline Client
Вопросов: 236
Ответов: 8362
Профиль | | #14
Добавлено: 07.11.05 19:05
ок, пасиб за просвящение