Pages: [1]   Go Down
Author Topic: porting perlin noise Java example doesn't work  (Read 282 times)
0 Members and 1 Guest are viewing this topic.
Enschede - The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to use an fixed point implementation of Perlin Improved noise in Arduino.
http://mrl.nyu.edu/~perlin/noise/INoise.java

I've already simplified some part and made an Arduino simulator in Processing. In the original code (link above) the arrays are generated on setup, but I put the arrays already in the code . This is modification tested and works in Processing.

I would like to port the Processing to Arduino. Steps made:
- converted all the int's to long, since Java ints are 4 bytes and Arduino ints 2 bytes (but longs are 4 bytes).
- Replaced the Math.min function with the min function in Arduino.

I run the code on an Arduino Mega1280 (since the UNO has not enough memory). I will optimise later, but I first want to have a setup with the less changes possible working.

In Arduino and don't seem to get the right result.
Do I miss something when porting this code to Arduino?


In both my setups I print a result off the noise to the monitor (Serial.print and print).

The Processing code (copy and past this in Processing 2.0):

Code:
// this version works, but porting this to Arduino (in this case the Mega because of memory) not.

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

int fadeArray[] = {
0,    0,    0,    0,    0,    0,    0,    0,    1,    1,    2,    3,    3,    4,    6,    7,
9,    10,   12,   14,   17,   19,   22,   25,   29,   32,   36,   40,   45,   49,   54,   60,
65,   71,   77,   84,   91,   98,   105,  113,  121,  130,  139,  148,  158,  167,  178,  188,
199,  211,  222,  234,  247,  259,  273,  286,  300,  314,  329,  344,  359,  374,  390,  407,
424,  441,  458,  476,  494,  512,  531,  550,  570,  589,  609,  630,  651,  672,  693,  715,
737,  759,  782,  805,  828,  851,  875,  899,  923,  948,  973,  998,  1023, 1049, 1074, 1100,
1127, 1153, 1180, 1207, 1234, 1261, 1289, 1316, 1344, 1372, 1400, 1429, 1457, 1486, 1515, 1543,
1572, 1602, 1631, 1660, 1690, 1719, 1749, 1778, 1808, 1838, 1868, 1898, 1928, 1958, 1988, 2018,
2048, 2077, 2107, 2137, 2167, 2197, 2227, 2257, 2287, 2317, 2346, 2376, 2405, 2435, 2464, 2493,
2523, 2552, 2580, 2609, 2638, 2666, 2695, 2723, 2751, 2779, 2806, 2834, 2861, 2888, 2915, 2942,
2968, 2995, 3021, 3046, 3072, 3097, 3122, 3147, 3172, 3196, 3220, 3244, 3267, 3290, 3313, 3336,
3358, 3380, 3402, 3423, 3444, 3465, 3486, 3506, 3525, 3545, 3564, 3583, 3601, 3619, 3637, 3654,
3672, 3688, 3705, 3721, 3736, 3751, 3766, 3781, 3795, 3809, 3822, 3836, 3848, 3861, 3873, 3884,
3896, 3907, 3917, 3928, 3937, 3947, 3956, 3965, 3974, 3982, 3990, 3997, 4004, 4011, 4018, 4024,
4030, 4035, 4041, 4046, 4050, 4055, 4059, 4063, 4066, 4070, 4073, 4076, 4078, 4081, 4083, 4085,
4086, 4088, 4089, 4091, 4092, 4092, 4093, 4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095,
};

int amountOfLights = 20;

int perlinTimeInc = 1000;
int perlinXInc    = 1000;
int perlinTimePosition = 0;

void setup()
{ size(400,400);
  frameRate(25);
}

void draw()
{  
    for(int i=0;i<amountOfLights;i++)
    { int val = renderNoise(i*perlinXInc, 0, perlinTimePosition);
      
      if(val>127) print("*");
      else        print("-");
    }  
    
    // go a step further in time (input for y function in perlin noise)
    perlinTimePosition = perlinTimePosition + perlinTimeInc;  
 
    println();
}

int renderNoise(int x, int y, int z)
{ return 137 + (inoise(x, y, z)/512);
}

int inoise(int x, int y, int z) {
 
  int X = x>>16 & 255, Y = y>>16 & 255, Z = z>>16 & 255, N = 1<<16;
  x &= N-1; y &= N-1; z &= N-1;
 
  int u=fade(x),v=fade(y),w=fade(z), A=p[X  ]+Y, AA=p[A]+Z, AB=p[A+1]+Z,
                                     B=p[X+1]+Y, BA=p[B]+Z, BB=p[B+1]+Z;
  return lerp(w, lerp(v, lerp(u, grad(p[AA  ], x   , y   , z   ),  
                                 grad(p[BA  ], x-N , y   , z   )),
                         lerp(u, grad(p[AB  ], x   , y-N , z   ),  
                                 grad(p[BB  ], x-N , y-N , z   ))),
                 lerp(v, lerp(u, grad(p[AA+1], x   , y   , z-N ),  
                                 grad(p[BA+1], x-N , y   , z-N )),
                         lerp(u, grad(p[AB+1], x   , y-N , z-N ),
                                 grad(p[BB+1], x-N , y-N , z-N ))));
}
 
int lerp(int t, int a, int b) { return a + (t * (b - a) >> 12); }
 
int grad(int hash, int x, int y, int z) {
  int h = hash&15, u = h<8?x:y, v = h<4?y:h==12||h==14?x:z;
  return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
}
 
int fade(int t) {
  int t0 = fadeArray[t >> 8], t1 = fadeArray[Math.min(255, (t >> 8) + 1)];
  return t0 + ( (t & 255) * (t1 - t0) >> 8 );
}

The Arduino code (in a reply, because message length is exceeded).

As attachment 2 screenshots with of the monitor (to see the smooth "perlin" movement in Processing).


* arduino monitor.png (8.9 KB, 127x327 - viewed 8 times.)

* processing monitor.png (8.98 KB, 146x286 - viewed 10 times.)
Logged

Enschede - The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The Arduino code (for what it's worth, since I hardly modified anything as you can read in my first post):

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

long fadeArray[] = {
0,    0,    0,    0,    0,    0,    0,    0,    1,    1,    2,    3,    3,    4,    6,    7,
9,    10,   12,   14,   17,   19,   22,   25,   29,   32,   36,   40,   45,   49,   54,   60,
65,   71,   77,   84,   91,   98,   105,  113,  121,  130,  139,  148,  158,  167,  178,  188,
199,  211,  222,  234,  247,  259,  273,  286,  300,  314,  329,  344,  359,  374,  390,  407,
424,  441,  458,  476,  494,  512,  531,  550,  570,  589,  609,  630,  651,  672,  693,  715,
737,  759,  782,  805,  828,  851,  875,  899,  923,  948,  973,  998,  1023, 1049, 1074, 1100,
1127, 1153, 1180, 1207, 1234, 1261, 1289, 1316, 1344, 1372, 1400, 1429, 1457, 1486, 1515, 1543,
1572, 1602, 1631, 1660, 1690, 1719, 1749, 1778, 1808, 1838, 1868, 1898, 1928, 1958, 1988, 2018,
2048, 2077, 2107, 2137, 2167, 2197, 2227, 2257, 2287, 2317, 2346, 2376, 2405, 2435, 2464, 2493,
2523, 2552, 2580, 2609, 2638, 2666, 2695, 2723, 2751, 2779, 2806, 2834, 2861, 2888, 2915, 2942,
2968, 2995, 3021, 3046, 3072, 3097, 3122, 3147, 3172, 3196, 3220, 3244, 3267, 3290, 3313, 3336,
3358, 3380, 3402, 3423, 3444, 3465, 3486, 3506, 3525, 3545, 3564, 3583, 3601, 3619, 3637, 3654,
3672, 3688, 3705, 3721, 3736, 3751, 3766, 3781, 3795, 3809, 3822, 3836, 3848, 3861, 3873, 3884,
3896, 3907, 3917, 3928, 3937, 3947, 3956, 3965, 3974, 3982, 3990, 3997, 4004, 4011, 4018, 4024,
4030, 4035, 4041, 4046, 4050, 4055, 4059, 4063, 4066, 4070, 4073, 4076, 4078, 4081, 4083, 4085,
4086, 4088, 4089, 4091, 4092, 4092, 4093, 4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095,
};

int amountOfLights = 20;

long perlinTimeInc = 1000L;
long perlinXInc    = 1000L;
long perlinTimePosition = 0;

void setup()
{   Serial.begin(57600);
}

void loop()
{  
    for(int i=0;i<amountOfLights;i++)
    { int val = renderNoise(i*perlinXInc, 0, perlinTimePosition);
      
      if(val>127) Serial.print("*");
      else        Serial.print("-");
    }
    
    // go a step further in time (input for y function in perlin noise)
    perlinTimePosition = perlinTimePosition + perlinTimeInc;  
    
    Serial.println();
    
    delay(50);
}

int renderNoise(long x, long y, long z)
{ return 137 + (inoise(x, y, z)/512);
}

long inoise(long x, long y, long z)
{
  long X = x>>16 & 255, Y = y>>16 & 255, Z = z>>16 & 255, N = 1<<16;
  x &= N-1; y &= N-1; z &= N-1;
 
  long u=fade(x),v=fade(y),w=fade(z), A=p[X  ]+Y, AA=p[A]+Z, AB=p[A+1]+Z,
                                     B=p[X+1]+Y, BA=p[B]+Z, BB=p[B+1]+Z;
  return lerp(w, lerp(v, lerp(u, grad(p[AA  ], x   , y   , z   ),  
                                 grad(p[BA  ], x-N , y   , z   )),
                         lerp(u, grad(p[AB  ], x   , y-N , z   ),  
                                 grad(p[BB  ], x-N , y-N , z   ))),
                 lerp(v, lerp(u, grad(p[AA+1], x   , y   , z-N ),  
                                 grad(p[BA+1], x-N , y   , z-N )),
                         lerp(u, grad(p[AB+1], x   , y-N , z-N ),
                                 grad(p[BB+1], x-N , y-N , z-N ))));
}
  
long lerp(long t, long a, long b) { return a + (t * (b - a) >> 12); }
 
long grad(long hash, long x, long y, long z)
{ long h = hash&15, u = h<8?x:y, v = h<4?y:h==12||h==14?x:z;
  return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
}
 
long fade(long t) {
  long t0 = fadeArray[t >> 8], t1 = fadeArray[min(255, (t >> 8) + 1)];
  return t0 + ( (t & 255) * (t1 - t0) >> 8 );
}
Logged

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12520
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Given that you have two implementations on different platforms and only one works, I suggest you set up a standard test case and add trace output to both implementations so that you can see at what point their behaviour diverges.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Enschede - The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Peter,
The code I've posted is my standard test case and in the screenshots I've showed the trace (and the difference). But I have no clue what goes wrong, probably something with different interpretation of datatypes?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 285
Posts: 25632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Are those tables constants?
Why aren't they in flash (PROGMEM) ?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Enschede - The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

They are constants and in the end I will place them in Flash memory (I've already made a version that does that). But in order to compare good and create a minimal working version I've tried to make to versions that are equal in Processing/Arduino.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 285
Posts: 25632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try
Code:
N = 1L << 16;
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Enschede - The Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Great, that works! I did it already with the upper integers, but overlooked this one.

Thanks.
Logged

Pages: [1]   Go Up
Jump to: