Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Проблема с равномерным расположением(размещением) N точек в заданной области (http://www.flasher.ru/forum/showthread.php?t=158040)

СлаваRa 14.06.2011 14:05

Проблема с равномерным расположением(размещением) N точек в заданной области
 
Дана прямоугольная область, ширина и высота известны, дано N(вводится пользователем) точек, необходимо расположить эти точки равномерно по области. Загвоздка в том, что под словом равномерно подразумевается, что любая точка должна быть равноудалена от соседних (по x и y осям, т.е. диагональ не учитывается).

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

marat_sa 14.06.2011 14:21

В хаотичном порядке или в виде таблицы - строки, столбцы?

incvizitor 14.06.2011 14:40

Если таблицы то:

1 - Собираем все точки в массив
2 - Смотрим сколько строчек и столбцов у нас получается.
3 - По циклу раставляем все точки по принципу:
Код AS3:

obj.x = (canvas.width / (nCollumns + 1)) * (i % nCollumns + 1);
obj.y = (canvas.height / (nRows + 1)) * (Math.floor(i / nCollumns) + 1);


olexandr 14.06.2011 14:42

я так понимаю, что в виде таблицы
в чем проблема? определить количество строк и столбцов что-ли?

silin 14.06.2011 19:20

вроде бы у такой задачки нет аналитического решения, только численно
вот эксперимент, попытка получить равноудаленные точки в прямоугольнике:
считаем, что все точки одинаково заряженные частицы и двигаем их в соответствии с силой отталкивания каждой от остальных и от стенок - должно бы устаканится, но реально что-то не очень..
но вообще как вариант может сработать, там enterFrame только для посмотреть, считать-то можно просто в цикле и останавливать при какой-то точности
Код AS3:

public class Main extends Sprite
{
 
        private var rect:Rectangle = new Rectangle(50, 50, 400, 300);
        private var points:Array /*Sprite*/ = [];
        private var num:int = 48;
 
        public function Main():void
        {
                this.graphics.lineStyle(0, 0x000000);
                this.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
                // частицы
                for (var i:int = 0; i < num; i++)
                {
                        var item:Sprite = new Sprite();
                        item.graphics.beginFill(0x0000FF);
                        item.graphics.drawCircle(0, 0, 10);
                        item.x = rect.x + rect.width * Math.random();
                        item.y = rect.y + rect.height * Math.random();
                        points.push(addChild(item));
 
                }
                // считаем-смотрим
                this.addEventListener(Event.ENTER_FRAME, enterFrame);
        }
 
        private function enterFrame(event:Event):void
        {
                for (var i:int = 0; i < num; i++)
                {
                        var item:Sprite = points[i];
                        var fX:Number = 0;
                        var fY:Number = 0;
                        var dX:Number;
                        var dY:Number;
                        var r:Number;
                        var fi:Number;
                        // отталкивание от других частиц
                        for (var j:int = i + 1; j < num; j++)
                        {
                                dX = points[j].x - item.x;
                                dY = points[j].y - item.y;
                                r = dX * dX + dY * dY;
                                fi = Math.atan2(dY, dX);
                                //сила отталкивания
                                fX += Math.cos(fi) / r;
                                fY += Math.sin(fi) / r;
 
                        }
 
                        // отталкивание от стенок
                        var d:Number = 3; // коефф. влияния стенок
                        fX -= d / (item.x - rect.left) / (item.x - rect.left);
                        fX += d / (item.x - rect.right) / (item.x - rect.right);
                        fY -= d / (item.y - rect.top) / (item.y - rect.top);
                        fY += d / (item.y - rect.bottom) / (item.y - rect.bottom);
 
                        var p:Number = 1e3;// * (1 + 0.2 * Math.random());
                        item.x -= p * fX;
                        item.y -= p * fY;
 
                        // проверка границ
                        if (item.x < rect.left)
                                item.x += 2 * (item.x - rect.left);
                        if (item.y < rect.top)
                                item.y += 2 * (item.y - rect.top);
                        if (item.x > rect.right)
                                item.x += 2 * (rect.right - item.x);
                        if (item.y > rect.bottom)
                                item.y += 2 * (rect.bottom - item.y);
 
                }
        }
}


СлаваRa 14.06.2011 19:34

2silin, Спасибо за идею.
Буду пробовать, если толковое решение найду, выложу код сюда.

i.o. 14.06.2011 19:50

А если построить сетку из равносторонних треугольников? По-моему как раз - точка идеально "равноудалена от соседних"... Может ошибаюсь. Может вообще не в тему :)


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

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