Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   API приложений и сред (http://www.flasher.ru/forum/forumdisplay.php?f=61)
-   -   [Papervision] Не правильная работа Math.random() или ошибка геометрии? (http://www.flasher.ru/forum/showthread.php?t=150652)

willis83 15.02.2011 21:09

Не правильная работа Math.random() или ошибка геометрии?
 
Возникла необходимость нарисовать сферу из рандомно расположенных пикселей, для рандомного распределения пикселей по поверхности сферы с центром в начале координатной сетки взял формулу

Код AS3:

Math.pow(radius,2) = Math.pow(myx,2) + Math.pow(myy,2) + Math.pow(myz,2);

Далее делаю следующее:

Код AS3:

var mypix:Pixels = new Pixels(pixLayer);
var cx:Number,cy:Number,cz:Number, radius:Number = 1200;
 
for(var i = 0; i < 1000; i++) {
          cx = prepCoord(Math.floor(Math.random()*radius));
        cy = prepCoord(Math.floor(Math.random()*radius));
        cz = prepCoord(Math.sqrt(Math.pow(radius,2) - Math.pow(cx,2) - Math.pow(cy,2)));
 
        mypix.addPixel3D(new Pixel3D(0xFFFFFFFF,cx,cy,cz));
};

Функция prepCoord умножает входящее значение на -1 с вероятностью 50/50 и возвращает его.

Сфера получается, но почему-то пиксели распределяются не равномерно по поверхности сферы, большая их концентрация приходится на полюса сферы, а на экваторах пикселей практически нет, получается как бы 2 полусферы. В чём ошибка?

Alexd21 15.02.2011 22:32

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

вот примеры:
http://flashgameblogs.ru/blog/actionscript/204.html
http://flash-mx.ru/forum/topic_show.pl?tid=2521

искал по-быстрому, так что наверняка есть еще варианты кодов.

Alex Lexcuk 15.02.2011 23:23

Очень сильно сложно сделать сферу из рандомных точек, давно пробовал, там алгоритмы это такая жесть и процессор кушают не слабо, но мне нужно было подобие октаэдра сделать те. сгенерить сферу из случайно разбросанных точек определенного числа треугольников. можно простое решение в 3Дмаксе кажется есть токая функция - фигура из определеного числа треугольных граней. вот ееможно сделать и чуток добавить рандомности в координаты ее вершин.

willis83 16.02.2011 00:34

Спасибо за помощь, буду знать!

Функционер 16.02.2011 01:18

Вложений: 1
такая?

willis83 16.02.2011 11:01

похож, но на экваторах у меня вообще практически отсутствуют пиксели. А чем вы такую подсветку сделали?

Функционер 16.02.2011 11:11

Это блюр к слою.

Добавлено через 6 минут
Код AS3:

package
{
        import flash.events.Event;
        import flash.filters.BlurFilter;
        import org.papervision3d.core.effects.BitmapLayerEffect;
        import org.papervision3d.core.effects.utils.BitmapClearMode;
        import org.papervision3d.core.geom.Pixels;
        import org.papervision3d.core.geom.renderables.Pixel3D;
        import org.papervision3d.view.BasicView;
        import org.papervision3d.view.layer.BitmapEffectLayer;
 
        public class Main extends BasicView
        {
                private var pixels:Pixels;
                private var rotateX:Number;
                private var rotateY:Number;
 
                public function Main()
                {
                        super(0, 0, true, true);
 
                        camera.z=-500;
 
                        rotateX=rotateY=0;
 
                        var layer:BitmapEffectLayer=new BitmapEffectLayer(viewport, 800, 800, true, 0, BitmapClearMode.CLEAR_PRE, true);
                        viewport.containerSprite.addLayer(layer);
                        layer.addEffect(new BitmapLayerEffect(new BlurFilter(8, 8, 4), false));
 
                        pixels=new Pixels(layer);
                        scene.addChild(pixels);
 
                        for(var i:int=0; i < 3000; i++)
                        {
                                var theta1:Number=360 * Math.random() * Math.PI / 180;
                                var theta2:Number=(180 * Math.random() - 90) * Math.PI / 180;
                                var radius:Number=200;
                                var xx:Number=radius * Math.cos(theta2) * Math.sin(theta1);
                                var yy:Number=radius * Math.sin(theta2);
                                var zz:Number=radius * Math.cos(theta2) * Math.cos(theta1);
                                var p:Pixel3D=new Pixel3D((0xffff0000), xx, yy, zz);
                                pixels.addPixel3D(p);
 
                        }
 
                        addEventListener(Event.ENTER_FRAME, onFrame);
                }
 
                private function onFrame(e:Event):void
                {
                        rotateX+=(-viewport.containerSprite.mouseX - rotateX) * 0.1;
                        rotateY+=(-viewport.containerSprite.mouseY - rotateY) * 0.1;
                        pixels.rotationY=rotateX;
                        pixels.rotationX=rotateY;
 
                        startRendering();
                }
        }
}


willis83 16.02.2011 11:37

хм интересено.... вы как-то через вектора делаете. Я по формуле - квадрат радиуса равен сумме квадратов координат.

Dima_DPE 16.02.2011 18:55

Формулы одинаковые, только вид разный. Вы используете даже не формулу, а уравнение сферы, по крайней мере меня так учили их разделять. А Функционер предлогает использовать тригонометрические уравнения, задающие сферу как систему функций x=x(t), y=y(t) и z=z(t).

Что быстрее возвести три раза в степерь и взять корень или вычеслить два синуса и косинуса угла при построении не знаю, вам решать. Зато вам хватит Math.random и сфера будет более менее однородная

willis83 16.02.2011 20:02

Dima_DPE, Что касается первой части вашего поста, то это не одна формула разного вида, если вы присмотритесь то Функционер сперва рандомом определяет направления(вектора), а потом по ним просчитывает каждую координату, а в способе который использовал я , х и у просчитываются рандомом а z по формуле квадратов... и результат отличается даже наглядно.И я думаю что для определённых задач один из способов будет более подходящий. Суть топика была в рандоме, и она уже раскрыта.

Что касается второй части вашего поста, то тут данная деталь не критична, т.к. этот алгоритм выполняется не каждый фрейм, а только при определении пикселей, далее же движок просчитывает пикселя на основе своих алгоритмов, абсолютно одинаково что у меня, что у Функционера, поэтому сотня лишних миллисекунд при создании сферы будет не в тяжесть конечному пользователю...


Часовой пояс GMT +4, время: 20:06.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.