• Как узнать сложность кода при наличии цикла с неизвестными параметрами?

    Griboks
    @Griboks
    Nightmare A, профайлер - это основной метод анализа сложности кода. Вся теория - попытка предсказать работу профайлера. Но раз у вас код в виде чёрного ящика, вы не сможете его предсказать. Например, у вас могут быть динамические границы цикла и т.п.
  • Есть ли смысл вкатываться в data science в 14 лет?

    Griboks
    @Griboks
    Jacen11, а может лучше не быть тупым пьяным соленым школяром?
  • Есть ли смысл вкатываться в data science в 14 лет?

    Griboks
    @Griboks
    Jacen11, а я видел статистику, что военные живут лучше гопников. И что дальше?)
  • Есть ли смысл вкатываться в data science в 14 лет?

    Griboks
    @Griboks
    Jacen11, зачем в школе? Лучше уж в армии сразу: бесконечные тусы и вообще отвал башки.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru,
    Нет, давайте не отходить от задачи в этом вопросе.

    Так что в итоге? Даны квадраты параллельные осям, разного размера и разных координат. Они могут перемещаться, но не могут растягиваться и поворачиваться. Я правильно понимаю?
    Вы перенесите вычисление расстояния между квадратами в код Update().

    Оно и так находится там. Закэшировано только минимальное расстояние до соприкосновения, т.е (r1+r2)^2.
    И в моем варианте вместо && используйте &. Посмотрите, как изменится время работы.

    Вы не поверите, но результаты ухудшились. Вместо 27 fps стало 19.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru, Убедили, это читерство. Тогда давайте предположим, что объекты могут двигаться, растягиваться и поворачиваться, - по стандарту 2D игр.
    Нет, это вы умножте у вас в коде и потом сравните.

    Так у меня в коде float. Никто не использует целочисленные координаты в физических движках.
    Еще раз, высчитывание расстояния между квадратами через их углы - неправильно, когда они разного размера. Это какое-то другое расстояние.

    Нет, у меня используются координаты центра: unit1.centerX - unit2.centerX.
    просто персонаж кое где проваливается сквозь стену, а с другой стороны упирается в невидимое препятствие перед стеной.

    Ну так всё правильно. Это не баг, а фича, что при частых прыжках можно взлететь)
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru,
    А можно я тогда значение закеширую?

    Как вы его закэшируете, если оно изменяется каждый кадр? Никак.
    Я понимаю, если бы вы для каждого квадрата какие-то его свойства предподсчитали. Центр там, размер, что угодно.

    Я заранее просчитал вообще всё, что смог для квадрата.
    А так вы часть вычисления для пары объектов вне таймера считаете. Конечно у вас быстрее будет.

    Ну так в этом и есть суть замены квадратов на круги. Чтобы было быстрее! Наконец вы это поняли.
    Ну да, если квадраты одного размера, то это еще будет работать. А когда один размера 10x10, а другой - 5x5, это уже не работает. Там надо расстояние между (x1+5, y1+5) и (x2+2.5, y2+2.5) считать.

    Хорошо, умножьте обе части неравенства на 2. Теперь остались только целые числа, как вы и хотели.
    Да и у вас в коде радиусы везде разные считаются. Конечно, если считать неправильно, то у вас быстрее будет.

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

    Почему неправильно? Каких ошибок? В коде float, коллизии вычисляются. Забудьте про целые числа.
    Вечером напишу свой бенчмарк.

    Тогда с нетерпением буду ждать.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru,
    что за collisionDistance у вас там в коде? Там должен быть квадрат суммы радиусов.

    Это кеш расстояния столкновения. Я закэшировал все данные, кроме позиции юнита, как вы и предлагали, чтобы избавиться от "читинга".

    Что там за целое число-то? x1-x2 может быть половинчатым.

    Ага, 7 - 5 = 2.5, всегда из int получаю float при сложении)

    Радиус вписанной окружности может тоже быть половинчатым. Радиус описанной окружности - (длина квадрата)/sqrt(2).

    Ну хорошо, давайте закэшируем r=a/2*2. Теперь можно смело заявить, что алгоритм работает для целых чисел тоже. Впрочем, речь о целых числах никогда не шла.

    В принципе, можно свести все к целым числам, но тут надо лишние телодвижения сделать, их я в вашем коде не вижу.

    Вы, видимо, мало работали в геймдеве. Нет принципиальной разницы между координатами центра или угла. Это легко доказать, т.к. смещение системы координат не влияет на метрику (длину ветров/расстояние между точками).

    Во-вторых, давайте весь код. Непонятно, что вы там сделали.

    Хорошо, жду результатов замеров от вас с профайлером, супер-мега оптимизацией условий и, разумеется, максимальной деградацией формулы квадратов. Было бы чудесно построить графики, но у вас почему-то аллергия на питон.
    public class GameObject
    	{
    		public float LeftBorder, TopBorder, CenterX, CenterY, RightBorder, BottomBorder, R;
    	}
    
    
    	public static class CollisionEngine
    	{
    		private static readonly (GameObject unit1, GameObject unit2, float collisionDistance, bool collisionFlag)[] Collisions;
    
    		static CollisionEngine()
    		{
    			var units = new GameObject[1000];
    			var random = new Random();
    			for (var i = 0; i < units.Length; i++)
    			{
    				var xl = (float)(random.NextDouble() * 1000);
    				var yl = (float)(random.NextDouble() * 1000);
    				var r = (float)(random.NextDouble() * 10);
    				units[i] = new GameObject { LeftBorder = xl, TopBorder = yl, R = r, CenterX = xl + r, CenterY = yl + r, RightBorder = xl + 2 * r, BottomBorder = yl + 2 * r };
    			}
    
    			Collisions = (from unit1 in units from unit2 in units where unit1 != unit2 select (unit1, unit2, (unit1.R + unit2.R) * (unit1.R + unit2.R), false)).ToArray();
    		}
    
    		private static void Update()
    		{
    			for (var i = 0; i < Collisions.Length; i++)
    			{
    				var (unit1, unit2, collisionDistance, f) = Collisions[i];
    				// Check collisions here. Comment out needed algorithm.
    				// Exact quadratic algorithm.
    				Collisions[i].collisionFlag = unit1.LeftBorder <= unit2.RightBorder && unit2.LeftBorder <= unit1.RightBorder && unit1.TopBorder <= unit2.BottomBorder && unit2.TopBorder <= unit1.BottomBorder;
    				//Quick round algorithm.
    				// Collisions[i].collisionFlag = (unit1.centerX - unit2.centerX) * (unit1.centerX - unit2.centerX) + (unit1.centerY - unit2.centerY) * (unit1.centerY - unit2.centerY) <= collisionDistance;
    			}
    		}
    
    		public static float TestFPS()
    		{
    			const int n = 1000;
    			var s = new Stopwatch();
    			s.Start();
    			for (var i = 0; i < n; i++) Update();
    			s.Stop();
    			return n / (s.ElapsedMilliseconds / 1000f);
    		}
    	}
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru,
    Но умножения занимают сильно больше 1 такта, как для сложения/вычитания/сравнения.

    Плюс, в вашем решении нельзя обойтись только целыми числами. Даже если входные данные целые. Потому что радиусы, да и центры окружностей будут вещественными. Т.е. оно еще на порядки медленнее.

    Это, разумеется, полная ерунда. Никаких вещественных чисел не задействуется, потому что квадрат целого числа даёт целое число. А раз так, то, сюрприз, заменяем мега тяжёлое умножение на бинарный сдвиг.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru, я так понимаю, что цель ваших комментариев - это всех запутать и доказать мою ошибку. Что ж... Тогда давайте опустим бессмысленные спорты, создадим проект на Unity 3D (C#, .Net Framework 4.8) и напишем свою ECS для проверки коллизий.

    Проверяем два метода расчёта коллизий: через квадраты
    Collisions[i].collisionFlag = unit1.leftBorder <= unit2.rightBorder && unit2.leftBorder <= unit1.rightBorder && unit1.topBorder <= unit2.bottomBorder && unit2.topBorder <= unit1.bottomBorder;

    и через окружности
    Collisions[i].collisionFlag = (unit1.centerX - unit2.centerX) * (unit1.centerX - unit2.centerX) + (unit1.centerY - unit2.centerY) * (unit1.centerY - unit2.centerY) <= collisionDistance;
    .

    Добавим много юнитов на сцену, всё, что можно, заранее закэшируем. Затем посчитаем средний FPS за 1000 кадров.

    63ad68be70644414488746.png

    Как вы можете заметить, прирост производительности от "очень тяжёлого умножения" радиусов окружностей не просто значительный. Разрыв заметно увеличивается для больших сцен.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru, давайте посчитаем вместе. У вас 4 случая для оси Ox, т.е. 10 операций, всего на обе оси получается 20. А у меня только 8, и они универсальные, т.е. в 2,5 раза меньше.

    Если ещё учесть векторные процессоры, то нетрудно вычислить, скажем, fps игры при 5000 объектов на карте. (Но мне трудно, потому что я не знаю, как работают векторные условия. Возможно, это даже не векторные операции!)
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru,
    в геймдеве действительно, аппроксимируют фигуры всякими кругами-шарами

    Пишу простенькую игру,

    Но в этой задаче смысла так делать точно нет.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru,
    чем оно легче кучи проверок?

    Меньше сложность, поэтому быстрее работает.

    точнее, легче одной проверки?

    Проверок очень много как и других операций.
    В вашем примере max(x1, x2) <= min(x1 + w1, x2 + w2) можно увидеть и вызовы функции, и сортировку, и промежуточные сложения, и дерево ветвлений.

    Кроме того, вы забыли учесть произвольный поворот квадратов в пространстве (впроечем, автор вроде их не поворачивает).

    Напротив сравнить столкновение окружностей (x1-x2)^2+(y1-y2)^2<=(r1+r2)^2 занимает всего 8 операций независимо от поворота или размерности пространства, тяжёлые из которых - это вычитания.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru, суть в том, что эти вычисления намного легче кучи проверок, поэтому есть смысл их использовать в обмен на точность.
  • Как определить коллизию квадратов?

    Griboks
    @Griboks
    Wataru, тогда используйте радиус описанных или между ними в зависимости от требуемой погрешности.
  • Почему низкая скорость по wi-fi?

    Griboks
    @Griboks
    Drno, ну, если динамический и на основе приоритетов типов трафика, то я был не прав.
  • Почему низкая скорость по wi-fi?

    Griboks
    @Griboks
    Drno, так и трафик непостоянный. Если вы выделите по 8 мбит/с на каждого, а он будет использовать только 1, то 7 останутся в простое. Поэтому идея вовсе нелогичная, попахивает советским прошлым.

    Тут надо рассчитывать нагрузку по теории массового обслуживания.
  • Почему низкая скорость по wi-fi?

    Griboks
    @Griboks
    Шейпер я нпдеюсь стоит для клиентов и какой то контроллер, скорость ограничивать?)

    для начала надо туда шейпер поставить, прокси с зарезанием ненужного и какой то контролер точек вифи

    Что за бредовая идея ограничивать скорость и трафик в целом?)) Это называется QOS, и работает не через шейпер, а через очередь приоритетов в планировщике ресурсов (не знаю, как у вас называется).
  • Как получить диплом сред-спец образования программисту без техникума и 4 лет впустую?

    Griboks
    @Griboks
    Danil_Dm, всё вноситься. Покупка липовой бумажки - это устаревший метод. Сейчас ты как бы нанимаешь репетиторов на все экзамены по всем предметам, а затем их сдаёшь, получаешь официальную ведомость, затем тебе выдают диплом в зависимости от минимального требуемого срока обучения.
  • Как получить диплом сред-спец образования программисту без техникума и 4 лет впустую?

    Griboks
    @Griboks
    Геннадий, Я не предлагаю совершить преступление. Я указываю на один из способов получить диплом. Кстати, не такой уж он и нелегальный. Многие вузы/путяги позволяют купить диплом официально.