# Slope of Perlin Noise

**URL:** https://discourse.processing.org/t/slope-of-perlin-noise/2745
**Category:** Project Guidance
**Created:** [August 18, 2018, 8:42am UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745 "2018-08-18T08:42:56Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![aradarbel10](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@aradarbel10](https://discourse.processing.org/u/aradarbel10)
#### Post date: [August 18, 2018, 8:42am UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/1 "2018-08-18T08:42:56Z")

</div>

Hello,  
I am generating 1D noise using the `noise()` function, and I need to draw a line perpendicular to the perlin noise in the x position of the mouse.  
I tried calculating the slope of 2 points near each other, but the result is very inacurate.  
I don’t really mind to use another noise generation method, but I already have the perlin noise example in my code.

Thank you for any help,  
Arad.

---

<div class="post-metadata">

### Author: ![TheWizardBear](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thewizardbear/32/3552_2.png) [@TheWizardBear](https://discourse.processing.org/u/TheWizardBear)
#### Post date: [August 18, 2018, 9:18am UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/2 "2018-08-18T09:18:19Z")

</div>

> [@aradarbel10](#):
>
> I tried calculating the slope of 2 points near each other, but the result is very inacurate.

By this, do you mean that the two perlin noise values calculated aren’t very close to one another? Did you try dividing the co-ordinates by some factor (probably around 30), to get a more smooth line?

[Here](https://p5js.org/examples/math-noise-wave.html) is a example using perlin noise on the p5 website.

Also (especially if this isn’t your problem), it would be really helpful if you could post some code to show us what you are doing at the moment, and so that the problem can be better understood.

---

<div class="post-metadata">

### Author: ![aradarbel10](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@aradarbel10](https://discourse.processing.org/u/aradarbel10)
#### Post date: [August 18, 2018, 10:55am UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/3 "2018-08-18T10:55:19Z")

</div>

I am using a value for the resolution of the x axis, but when I increase it, something goes wrong…  
I’ll add the code so you can see it. I also made changes to the slope calculation. just averaging the slopes of the current position with lots of other points, but its working only on 4 points to each direction for some reason.  
I already added a player and an enemy class (I won’t include the enemy class because it is npt related to the problem and I am not actually using it now).  
The blue rectangle is the bounding box of the player, red line is the position, and green line is the angle.  
nothing is really working now, I am just trying to get the angle works.

```auto
int window_width = 900, window_height = 700;
int terrainResolutionX = 2;

int slope_offset = 4;

float xoff = 0.0;
float[] terrain = new float[window_width / terrainResolutionX + 1];

float playerRotation = 0;
float playerFloorLineB = 0;

int playerX = 0, playerY = 0;
int playerWidth = 40, playerHeight = 50;

int playerAcceleration = 2;
float playerVel = 0;
int playerMaxVel = 20;

boolean key_a = false, key_d = false;

int enemyCount = 0;
ArrayList<Enemy> enemies = new ArrayList<Enemy>();

char[] enemyTypes = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};

int score = 0;

void setup(){
  size(900, 700);
  
  playerX = window_width / 2;
  
  generateTerrain();
  
  for(int i = 0; i < 0; i++){
    newEnemy();
    print(enemies.get(i).enemyType);
  }
}

void draw() {
  background(255);
  
  updateKeysStates();
  
  playerX += playerVel;
  
  if(playerX > window_width - 1){
    playerX = window_width - 1;
  }else if(playerX < 0){
    playerX = 0;
  }
  
  if(playerVel < 0.25 && playerVel > -0.25){
    playerVel = 0;
  }
  
  float[] tempSlopes = new float[slope_offset * 2];
  float[] yValues = new float[slope_offset * 2];
  float playerSlope = 0;
  
  for(int i = 0; i < slope_offset * 2; i++){
    int operator = 0;
    if(i < slope_offset){
      operator = -1;
    }
    
    if(playerX + (i - 3 + operator) < slope_offset || playerX + (i - 3 + operator) > window_width - slope_offset){
      yValues[i] = terrain[playerX / terrainResolutionX];
    }else{
      yValues[i] = terrain[(playerX / terrainResolutionX) + (i - 3 + operator)];
    }
  }
  
  for(int i = 0; i < slope_offset * 2; i++){
    int operator = 0;
    if(i < slope_offset){
      operator = -1;
    }
    
    tempSlopes[i] = (terrain[playerX / terrainResolutionX] - yValues[i]) / (i - 3 + operator);
    playerSlope += tempSlopes[i];
  }
  
  playerSlope /= (slope_offset * 2);
  
  playerVel -= playerSlope * 0.3;
  
  if(playerVel > playerMaxVel){
    playerVel = playerMaxVel;
  }
  if(playerVel < -playerMaxVel){
    playerVel = -playerMaxVel;
  }
  
  playerVel -= 0.2 * playerVel;
  
  stroke(0);
  for(int i = 0; i < (window_width / terrainResolutionX) - 1; i++){
    line(i * terrainResolutionX, terrain[i], (i * terrainResolutionX) + 1, terrain[i + 1]);
  }
  
  stroke(255, 0, 0);
  line(playerX, terrain[(int)(playerX / terrainResolutionX)], playerX, terrain[(int)(playerX / terrainResolutionX)] - playerHeight);
  
  stroke(0, 255, 0);
  float angle1;
  angle1 = degrees(atan(playerSlope));
  float angle2 = 90 - angle1 + 90;
  float ratioA = playerHeight / sin(HALF_PI);
  float side1H = ratioA * sin(radians(angle2));
  float side2W = sqrt(pow(playerHeight / 2, 2) - pow(side1H, 2));
  line(playerX, terrain[playerX / terrainResolutionX], playerX - side1H, terrain[playerX / terrainResolutionX] - side2W);
    
  for(Enemy e : enemies){
    e.update();
    e.show();
  }
  
  float temp = 0;
  for(int i = enemies.size() - 1; i >= 0; i--){
    if(enemies.get(i).xPos >= window_width - 1 || enemies.get(i).xPos <= 1){
      temp++;
      enemies.remove(i);
    }else if(enemies.get(i).yPos + enemies.get(i).size / 2 >= terrain[floor(enemies.get(i).xPos / terrainResolutionX)]){
      temp++;
      enemies.remove(i);
    }
  }
  
  for(int i = 0; i < temp; i++){
    newEnemy();
  }
  
  fill(0);
  textSize(40);
  textAlign(LEFT, TOP);
  text(score, 10, 10);
  
  pushMatrix();
  
  noFill();
  stroke(0, 0, 255);
  translate(playerX, terrain[playerX / terrainResolutionX] - 0.5 * playerHeight);
  //rotate(radians(angle1));
  rect(-playerWidth / 2, -playerHeight / 2, playerWidth, playerHeight);
  
  popMatrix();
}

void generateTerrain(){
  for(int i = 0; i < window_width / terrainResolutionX; i++){
    xoff = xoff + .01;
    float n = noise(xoff) * 150;
    terrain[i] = window_height - n;
  }
}

void updateKeysStates(){
  if(key_a){
    playerVel -= playerAcceleration;
  }
  if(key_d){
    playerVel += playerAcceleration;
  }
}

void newEnemy(){
  enemies.add(new Enemy(random(60, 840), enemyTypes[(int)random(0, enemyTypes.length)], random(6, 9), random(-15, 15), random(25, 35)));
}

void keyPressed(){
  if(key == 'a'){
    key_a = true;
  }
  if(key == 'd'){
    key_d = true;
  }
}
void keyReleased(){
  if(key == 'a'){
    key_a = false;
  }
  if(key == 'd'){
    key_d = false;
  }
}

```

I you have any questions about the code, just ask me 🙂  
I need this really fast so I hope you have an answer.

---

<div class="post-metadata">

### Author: ![TheWizardBear](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thewizardbear/32/3552_2.png) [@TheWizardBear](https://discourse.processing.org/u/TheWizardBear)
#### Post date: [August 18, 2018, 12:10pm UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/4 "2018-08-18T12:10:16Z")

</div>

Is there another tab with the Enemy class?

---

<div class="post-metadata">

### Author: ![aradarbel10](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@aradarbel10](https://discourse.processing.org/u/aradarbel10)
#### Post date: [August 18, 2018, 12:28pm UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/5 "2018-08-18T12:28:18Z")

</div>

yes,

```auto
class Enemy{
  float xPos = 0, yPos = 0;
  float vel = 0, theta = 0;
  char enemyType = '0';
  float size;
  
  Enemy(float x, char type, float speed, float angle, float radius){
    xPos = x;
    enemyType = type;
    vel = speed;
    theta = angle;
    size = radius;
    yPos = -size;
  }
  
  void update(){
    float ratio = vel / degrees(sin(HALF_PI));
    float delta_x = ratio * degrees(sin(radians(theta)));
    float delta_y = sqrt((vel * vel) - (delta_x * delta_x));
    
    xPos += delta_x;
    yPos += delta_y;
    
    //print(delta_x, " , ", delta_y);
  }
  
  void show(){
    noStroke();
    
    if(enemyType == 'a'){
      fill(244, 66, 83);
    }
    if(enemyType == 'b'){
      fill(238, 65, 244);
    }
    if(enemyType == 'c'){
      fill(112, 65, 244);
    }
    if(enemyType == 'd'){
      fill(65, 169, 244);
    }
    if(enemyType == 'e'){
      fill(65, 244, 193);
    }
    if(enemyType == 'f'){
      fill(65, 244, 73);
    }
    if(enemyType == 'g'){
      fill(232, 244, 65);
    }
    if(enemyType == 'h'){
      fill(244, 169, 65);
    }
    
    ellipse(xPos, yPos, size, size);
    //println("hello!!! , ", xPos, " , ", yPos);
  }
  
};

```

---

<div class="post-metadata">

### Author: ![TheWizardBear](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thewizardbear/32/3552_2.png) [@TheWizardBear](https://discourse.processing.org/u/TheWizardBear)
#### Post date: [August 18, 2018, 1:02pm UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/6 "2018-08-18T13:02:07Z")

</div>

> [@aradarbel10](#):
>
> line perpendicular to the perlin noise

Ah, I think I understand what you mean now.  
What you want to do is calculate the gradient of a tangent to a part of the terrain and then find the line perpendicular to it.  
Here is some **psuedo** code for it:

```auto
x1 = player x - 1 pixel
x2 = player x
y1 = height at the pixel 1 pixel before the one the player is on.
y2 = height at the pixel the player is on

perpendicularLineGradient= (x1-x2)/(y1-y2) [I think]

lineLength = 20

scale = sqrt(lineLength^2/(perpendicularLineGradient^2+1))

line(x2, y2, x2 + scale, y2 + perpendicularLineGradient * scale)

```

I’m not sure I got this quite right; it’s quite a lot of math. If it isn’t correct then let me know.  
[Here](http://www.bbc.co.uk/schools/gcsebitesize/maths/algebra/graphshirev1.shtml) is a BBC bitesize page on calculating equations of perpendicular lines.

When I say pixel, any unit will do as long as you keep it the same throughout.

Also, the last bit involving the variable I named “scale” is so that the length of the lines is constant, rather than just having a constant x or y length of the line.

I really hope this works and makes sense. 😂

Feel free to ask me any questions.

---

<div class="post-metadata">

### Author: ![aradarbel10](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@aradarbel10](https://discourse.processing.org/u/aradarbel10)
#### Post date: [August 18, 2018, 1:22pm UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/7 "2018-08-18T13:22:29Z")

</div>

> perpendicularLineGradient= (x1-x2)/(y1-y2) [I think]

its `(y - y)/(x-x)`

I already tried it, and it wast precise enough.  
Because Im short of time I decided to stick with a sine wave, that is simpler.

---

<div class="post-metadata">

### Author: ![TheWizardBear](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/thewizardbear/32/3552_2.png) [@TheWizardBear](https://discourse.processing.org/u/TheWizardBear)
#### Post date: [August 18, 2018, 1:24pm UTC](https://discourse.processing.org/t/slope-of-perlin-noise/2745/8 "2018-08-18T13:24:15Z")

</div>

No I think

> [@aradarbel10](#):
>
> (y - y)/(x-x).

is the gradient of the line but -(x-x)/(y-y) is gradient of the perpendicular line.
