Шум Перлина реализован в php, неопределенное смещение в таблице перестановок, но индекс определен - PullRequest
1 голос
/ 19 января 2020

Итак, я решил написать реализацию перлин-шума в php. Не спрашивай меня почему, я забыл. После этого: https://flafla2.github.io/2014/08/09/perlinnoise.html, я дошел до того, что должен получить некоторые результаты. Октавы еще не работали, но векторы должны делать свое дело.

Оскорбляющий код внизу поста.

У меня было несколько ошибок при реализации его как класса (серьезно, чья идея состояла в том, чтобы сделать обязательным предисловие каждой переменной в классе к $this->? Это почти дало мне буквальную головную боль, исправляя все ошибки, которые я сделал), но я думаю, что поймал их всех. У меня были некоторые проблемы с удвоением матрицы перестановок, но это также сделано. Я знаю это, потому что я напечатал это. Однако, когда я пытаюсь получить вещь ha sh, я получаю страницу, полную PHP Notice: Undefined offset: 1 in perlin.php (0, а также 1).

Это приводит к группе переменных, которые должны быть целыми числами. null. У меня есть все функции, что ожидать, поэтому я получаю PHP Fatal error: Uncaught TypeError: Argument 1 passed to perlin::grad() must be of the type int, null given, called in perlin.php on line 56 and defined in perlin.php:73

Больше всего меня смущает то, что массив, который жалуется, определяется в диапазоне от 0 до 511 (включительно).

Мне не хватает важной информации, такой как разница между индексом и смещением?

Код:

<?php

class perlin{
    public function __construct(){
        $p=array_merge($this->permutation,$this->permutation);
        print_r($p);
    }

    private $permutation=array(111, 176, 195, 194, 99, 88, 206, 7, 84, 2, 246, 181, 221, 69, 249, 3, 47, 223, 154, 26, 65, 142, 178, 100, 128, 134, 254, 94, 78, 204, 59, 98, 48, 171, 80, 125, 190, 86, 225, 138, 57, 144, 16, 143, 169, 162, 139, 252, 147, 182, 67, 179, 220, 160, 81, 96, 132, 82, 148, 72, 64, 242, 255, 137, 74, 185, 212, 19, 218, 256, 101, 130, 39, 234, 41, 115, 228, 230, 214, 45, 107, 251, 117, 91, 68, 49, 37, 208, 207, 192, 168, 232, 133, 23, 54, 106, 153, 247, 87, 200, 34, 187, 25, 124, 17, 114, 245, 248, 157, 77, 9, 219, 120, 236, 183, 79, 50, 42, 250, 189, 102, 227, 243, 83, 159, 62, 156, 151, 75, 13, 177, 158, 253, 196, 166, 103, 118, 32, 229, 235, 170, 15, 108, 58, 21, 73, 31, 70, 89, 203, 46, 205, 110, 150, 113, 43, 199, 29, 193, 40, 1, 60, 152, 6, 104, 129, 175, 36, 8, 222, 135, 85, 198, 123, 149, 238, 231, 164, 63, 76, 38, 20, 184, 188, 4, 12, 119, 14, 240, 105, 30, 210, 27, 241, 224, 239, 10, 66, 116, 167, 56, 140, 95, 126, 217, 92, 51, 55, 213, 155, 201, 161, 244, 197, 180, 71, 44, 215, 172, 18, 165, 35, 131, 186, 202, 22, 24, 121, 226, 33, 93, 163, 211, 191, 61, 53, 28, 136, 216, 122, 237, 173, 112, 209, 97, 145, 233, 146, 174, 141, 5, 52, 11, 109, 127, 90);
    //generated by seq 1 256|shuf|sed 's/$/,/g'|tr '\n' ' '

    public $repeat=0;

    private $p=array();

    private function inc($num){
        $num++;
        if($this->repeat>0){
            $num%=$this->repeat;
        }
        return $num;
    }

    private function fade(float $t){
        return $t*$t*$t*($t*($t*6+15)+10);
    }

    public function perlin(float $x,float $y,float $z){
        if($this->repeat>0){
            $x=$x%$this->repeat;
            $y=$y%$this->repeat;
            $z=$z%$this->repeat;
        }
        $xi=(int)($x) & 255;
        $yi=(int)($y) & 255;
        $zi=(int)($z) & 255;
        $xf=$x-(int)($x);
        $yf=$y-(int)($y);
        $zf=$z-(int)($z);

        echo "$xi $yi $zi $xf $yf $zf<br>\n\n";

        $u=$this->fade($xf);
        $v=$this->fade($yf);
        $w=$this->fade($zf);

        $aaa=$this->p[$this->p[$this->p[           $xi ]+           $yi ]+           $zi ];
        $aba=$this->p[$this->p[$this->p[           $xi ]+$this->inc($yi)]+           $zi ];
        $aab=$this->p[$this->p[$this->p[           $xi ]+           $yi ]+$this->inc($zi)];
        $abb=$this->p[$this->p[$this->p[           $xi ]+$this->inc($yi)]+$this->inc($zi)];
        $baa=$this->p[$this->p[$this->p[$this->inc($xi)]+           $yi ]+           $zi ];
        $bba=$this->p[$this->p[$this->p[$this->inc($xi)]+$this->inc($yi)]+           $zi ];
        $bab=$this->p[$this->p[$this->p[$this->inc($xi)]+           $yi ]+$this->inc($zi)];
        $bbb=$this->p[$this->p[$this->p[$this->inc($xi)]+$this->inc($yi)]+$this->inc($zi)];

        $x1=$this->lerp($this->grad($aaa,$xf,$yf,$zf),
                        $this->grad($baa,$xf-1,$yf,$zf),$u);
        $x2=$this->lerp($this->grad($aba,$xf,$yf-1,$zf),
                        $this->grad($bba,$xf-1,$yf-1,$zf),$u);
        $y1=$this->lerp($x1,$x2,v);

        $x1=$this->lerp($this->grad($aab,$xf,$yf,$zf-1),
                        $this->grad($bab,$xf-1,$yf,$zf-1),$u);
        $x2=$this->lerp($this->grad($abb,$xf,$yf-1,$zf-1),
                        $this->grad($bbb,$xf-1,$yf-1,$zf-1),$u);
        $y2=$this->lerp($x1,$x2,v);

        return ($this->lerp($y1,$y2,w)+1)/2;
    }



    private function grad(int $hash,float $x,float $y,float $z){
        switch($hash & 0xF){
            case 0x0: return $x+$y;
            case 0x1: return -$x + $y;
            case 0x2: return  $x - $y;
            case 0x3: return -$x - $y;
            case 0x4: return  $x + $z;
            case 0x5: return -$x + $z;
            case 0x6: return  $x - $z;
            case 0x7: return -$x - $z;
            case 0x8: return  $y + $z;
            case 0x9: return -$y + $z;
            case 0xA: return  $y - $z;
            case 0xB: return -$y - $z;
            case 0xC: return  $y + $x;
            case 0xD: return -$y + $z;
            case 0xE: return  $y - $x;
            case 0xF: return -$y - $z;
            default: return 0;
        }
    }

    private function lerp(float $a,float $b,float $x){
        return $a+$x*($b-$a);
    }

}
?>
...