Страницы

Поиск по вопросам

четверг, 19 марта 2020 г.

Поиск клеток в радиусе от заданной

#php #оптимизация


Вход - X,Y,R. Соответственно, координаты центра и радиус.
Надо найти все, что внутри круга с такими параметрами.
Есть большое подозрение на быдлокод:
function getCellsByRadius($x,$y,$r){
    for($i=floor($y-$r);$i<=ceil($y+$r);$i++){//высота квадрата со стороной 2r. Искомый
круг точно не больше.
      for($j=floor($x-$r);$j<=ceil($x+$r);$j++){//ширина квадрата со стороной 2r
        $distance = sqrt(pow(($j - $x),2)+pow(($i - $y),2));//расстояние до каждой
точки квадрата
        if($distance<$r){
          $this->cells[$j][$i]='#999';
        }
      }
    }
    $this->cells[$x][$y]='#f00';
  }

Помогите, пожалуйста, разбыдлокодить. =(
P.S. можно проверять расстояние до точек, которые внутри квадрата +-r, но все ромба
x+r,y
x-r,y
x,y+r
x,y-r

Но мне кажется, что лишняя проверка этого ромба может только усугубить ситуацию.
Еще можно проверять только для четверти, а потом размножать на весь круг. Но опять
же, поворот может дорого обойтись.    


Ответы

Ответ 1



function getCellsByRadius($x,$y,$r,$ccircle,$ccenter){ $r2 = $r * $r; for($i=floor($y-$r);$i<=ceil($y+$r);$i++){ $dxmax2 = $r2 - ($y - $i) * ($y - $i); if ($dxmax2 < 0) continue; $dxmax = sqrt($dxmax2); $lower = floor($x-$dxmax); $upper = ceil($x+$dxmax); for($j=$lower;$j<=$upper;$j++){ $this->cells[$j][$i]=$ccircle; } } $this->cells[$x][$y]=$ccenter; } (Не уверен, что код правильный, я не знаток php. Может, где-то надо объявить локальные переменные.)

Ответ 2



чисто спортивный интерес. Решил просто матрицу заполнить 1, если в окружности сделал вот так $x=50; $y=25; $r=10; //грубо говоря тело вашей функции for ($i=-$r;$i<=$r;$i++) { $y1=ceil(sqrt(pow($r,2)-pow($i,2))); $cells[$x+$i]=array_fill($y-$y1,2*$y1+1,1); } вывел во так тут просто решил глянуть будет ли похоже на окружность for ($i=-$r;$i<=$r;$i++) { for ($j=-$r;$j<=$r;$j++) { if (array_key_exists($j+$y,$cells[$x+$i])) { echo $cells[$x+$i][$y+$j]; } else { echo'0'; } } echo '
'; } результат 000000000010000000000 000001111111111100000 000011111111111110000 001111111111111111100 001111111111111111100 011111111111111111110 111111111111111111111 111111111111111111111 111111111111111111111 111111111111111111111 111111111111111111111 111111111111111111111 111111111111111111111 111111111111111111111 111111111111111111111 011111111111111111110 001111111111111111100 001111111111111111100 000011111111111110000 000001111111111100000 000000000010000000000 Возможно гдето с округлением напутал, попробуйте. Единственное отличие что я присваиваю 1, а вы цвет ячейки. Единтсвееное что в коде нет - это присваивание цвета точки центра))) тут как говорится проще не сделаешь Вот непонятливый. Сам же в коде делал целые числа, зная что дроби не могут быть. Тогда как ты заставишь компьютер покрасить точку центра с координатами не являющимися целыми? Куда ты в своей окржности вписанной в квадрат 4х4 поставишь центр и покрасишь его другим цветом?ПО твоей логике он будет находится между пикселей что-ли?

Комментариев нет:

Отправить комментарий