# 'Spin the bottle' - 360 degrees with PVector

**URL:** <https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872>\
**Category:** Coding Questions\
**Created:** [November 25, 2022, 8:06pm UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872 "2022-11-25T20:06:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![acousticer](https://avatars.discourse-cdn.com/v4/letter/a/47e85d/32.png) [@acousticer](https://discourse.processing.org/u/acousticer)\
**Post date:** [November 25, 2022, 8:06pm UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872/1 "2022-11-25T20:06:06Z")

</div>

Can someone please tell me what I’m missing here to make this spin 360 degrees. I was able to do it without using PVectors but it doesn’t seem to work when I alter with code with PVectors. I’m still just getting the hang of them.

In the end, I want to produce a ‘spin the bottle’ type of loop but for now, this much would do - have it spin.

Thanks!

```auto

PVector radius; 
PVector angle; 
PVector aVel; 
PVector aAccel; 

void setup () {
  size (600, 600);
}

void draw () {
  background (255); 

  PVector location = new PVector (0.0, 0.0);
  PVector aVel = new PVector (0.0, 0.0); 
  PVector aAccel = new PVector (0.0, 0.0); 
  PVector radius = new PVector (150.0, 0.0);
  PVector angle = new PVector (0.0, 0.0); 

  translate (width/2, height/2); 

  location.x= radius.x * cos(angle.x); 
  location.y = radius.x * sin(angle.x); 
  fill (0); 
  stroke (0); 
  line (0, 0, location.x, location.y); 
  ellipse (location.x, location.y, 50, 50); 

  angle.add(aVel); 
  aVel.add(aAccel); 
}

```

My initial code is a copy from Daniel Schiffman’s video [youtube video](https://www.youtube.com/watch?v=znOBmOrtz_M&t=2s). It works.

```auto

float r = 150; 
float a = 0.0;

float aVel = 0.0; 
float aAccel = 0.001; 

void setup () {
  size (600,600); 
}

void draw () {
  background (255); 
  
  translate (width/2, height/2); 
  float x = r * cos(a); 
  float y = r * sin(a); 
  
  fill (0); 
  stroke (0); 
  line (0,0, x,y); 
  ellipse (x,y,50,50); 
  
  
  a += aVel; 
  aVel += aAccel; 
  aVel = constrain(aVel, 0,0.35); 

  
}

```

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [November 25, 2022, 8:42pm UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872/2 "2022-11-25T20:42:19Z")

</div>

Hi @acousticer,

Issue is here …

> [@acousticer](#):
>
> ```auto
> PVector location = new PVector (0.0, 0.0);
> PVector aVel = new PVector (0.0, 0.0); 
> PVector aAccel = new PVector (0.0, 0.0); 
> PVector radius = new PVector (150.0, 0.0);
> PVector angle = new PVector (0.0, 0.0); 
> 
> ```

You need to declare it outside of draw an modify only the values in draw, otherwise it will be always set to the declared values and the code below …

> [@acousticer](#):
>
> ```auto
> angle.add(aVel); 
> aVel.add(aAccel); 
> 
> ```

…has no effect.

Cheers  
— mnse

PS: s.th like this should work…

```auto
PVector radius; 
PVector angle; 
PVector aVel; 
PVector aAccel; 
PVector location;

void setup () {
  size (600, 600);
  location = new PVector (0.0, 0.0);
  aVel = new PVector (0.0, 0.0); 
  aAccel = new PVector (0.0, 0.0); 
  radius = new PVector (150.0, 0.0);
  angle = new PVector (0.0, 0.0); 
}

void draw () {
  background (255); 
  translate (width/2, height/2); 

  location.x= radius.x * cos(angle.x); 
  location.y = radius.x * sin(angle.x); 
  fill (0); 
  stroke (0); 
  line (0, 0, location.x, location.y); 
  ellipse (location.x, location.y, 50, 50); 

  angle.add(aVel); 
  aVel.add(aAccel); 
}

```

PPS: also your velocity and acceleration is 0 now (0+0=0). Fill with proper values …

---

<div class="post-metadata">

**Author:** ![acousticer](https://avatars.discourse-cdn.com/v4/letter/a/47e85d/32.png) [@acousticer](https://discourse.processing.org/u/acousticer)\
**Post date:** [November 25, 2022, 9:04pm UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872/3 "2022-11-25T21:04:50Z")

</div>

It worked @mnse. Thanks a lot! In hindsight, I should’ve noticed this. Glad that you spotted it.

---

<div class="post-metadata">

**Author:** ![acousticer](https://avatars.discourse-cdn.com/v4/letter/a/47e85d/32.png) [@acousticer](https://discourse.processing.org/u/acousticer)\
**Post date:** [November 25, 2022, 11:39pm UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872/4 "2022-11-25T23:39:54Z")

</div>

Could you give me advice on this next part too? I am hoping to have the background change colour to different colours each time the ball overlaps with another ball. The balls are from the same class and I have an ‘overlap’ function. It worked in an earlier iteration but no longer works now that I’ve implemented PVector.

The issue seems to be that everything happens at the start of the sketch and then never happens again.

This is my main sketch.

```auto
// MAIN SKETCH
PVector radius; 
PVector angle; 
PVector aVel; 
PVector aAccel; 
PVector location;

myObject movingBall; 
myObject a1;
myObject a10; 

void setup () {
  size (600, 600);
  background (255); 
  fill (0); 
  stroke (0); 

  location = new PVector (0.0, 0.0);
  aVel = new PVector (0.01, 0.0); 
  aAccel = new PVector (0.1, 0.0); 
  radius = new PVector (150.0, 0.0);
  angle = new PVector (0.0, 0.0); 

  movingBall = new myObject(0, 0, 30);
  a1 = new myObject (0, 0, 30);
  a10 = new myObject (0, 0, 30);
}

void draw () {

  // WHEN MOVING BALL OVERLAPS ANOTHER BALL, CHANGE BACKGROUND
  if (movingBall.overlaps(a1)) {
    background (255);
  } else if (movingBall.overlaps(a10)) {
    background (100);
  } else {
    background (180);
  }

  translate (width/2, height/2); 

  // ADDING FORCE 
  //PVector f = new PVector (0,0.1); 
  //aVel.add(f); 

  // Moving line 
  location.x= radius.x * cos(angle.x); 
  location.y = radius.x * sin(angle.x); 
  line (0, 0, location.x, location.y); 

  // Moving Ball 
  movingBall.location.x= radius.x * cos(angle.x); 
  movingBall.location.y = radius.x * sin(angle.x); 
  ellipse (movingBall.location.x, movingBall.location.y, movingBall.mass*movingBall.diameter, movingBall.mass*movingBall.diameter); 

  // Static balls 
  ellipse (a1.location.x+100, a1.location.y-100, 50, 50); 
  ellipse (a10.location.x-110, a10.location.y+110, 50, 50); 

  // ADDING FRICTION 
  //PVector friction = aVel.get(); 
  //friction.normalize(); 
  //friction.mult(-1); 
  //float c = -0.01; 
  //friction.mult(c); 
  //m.applyForce (c);  

  movingBall.display(); 
  a1.display();
  a10.display();

  angle.add(aVel); 
  //aVel.add(aAccel);
  //aVel.limit(0.2);
}

```

And, this is my class:

```auto
class myObject {

  float diameter; // So declare your variable
  float c1 = 180; 
  float c2 = 0; 

  PVector location; 
  PVector aVel; 
  PVector aAccel; 

  float mass; 

// CONSTRUCTOR
  myObject (float xPosit, float yPosit, float tempD) {

    location = new PVector (0, 0); 
    aVel = new PVector (0, 0); // Start at 0
    aAccel = new PVector (0, 0); // Start at 0

    location.x = xPosit; 
    location.y = yPosit;
    diameter = tempD; //

    mass = 1; //
    fill (0); 
  }

// OVERLAP FUNCTION 
  boolean overlaps (myObject other) {
    float d = dist(location.x, location.y, other.location.x, other.location.y); 
    if (d < diameter/2 + other.diameter/2) {
      return true;
    } else {
      return false;
    }
  }

  void display () {
    
    aVel.add(aAccel); 
    location.add(aVel); 
   
    aAccel.mult(0); // Clear out at end of every frame 
  }

  void applyForce (PVector force) {

    aAccel.add(force);
  }
} // END

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [November 26, 2022, 12:57am UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872/5 "2022-11-26T00:57:26Z")

</div>

Hello @acousticer ,

> [@acousticer](#):
>
> I am hoping to have the background change colour to different colours each time the ball overlaps with another ball.

You need to compare the two locations directly.

You are adding values to the location when displaying the ellipse and this will not work because the ellipse that is displayed is not at the location that you are comparing to.

Example with just PVectors:

```auto
PVector v0, v1;

void setup () 
  {
  size (500, 200);
  background(255); 
  fill(0); 
  noStroke(); 

  v0 = new PVector(0, height/2);
  v1 = new PVector (width/2, height/2);
  }

void draw () 
  { 
  if (v0.dist(v1) < 35)
    background(128, 255, 255);
  else
    background(255, 228, 255);
  
  // Moving
  circle (v0.x, v0.y, 20); 

  // Static balls 
  circle (v1.x, v1.y, 50);
  
  v0.x += 2;
  
  if (v0.x > width) 
    v0.x = 0;
  }

```

`:)`

---

<div class="post-metadata">

**Author:** ![acousticer](https://avatars.discourse-cdn.com/v4/letter/a/47e85d/32.png) [@acousticer](https://discourse.processing.org/u/acousticer)\
**Post date:** [November 27, 2022, 5:10pm UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872/6 "2022-11-27T17:10:06Z")

</div>

@mnse @glv Thanks for helping me! Could you please take a look over the code again? I’ve made some changes and have realised that I won’t need to implement forces, but I am still having trouble with this overlap function since I restarted. I know that it should work but I can’t figure it out why it’s not. I hope that you don’t mind. Thanks in advance!

The background should change to a different colour when the mover hits a ‘bob’.

```auto
bob a1; 
bob a2; 
bob a3; 
bob a4; 
bob a5; 
bob a6; 
bob a7; 
bob a8; 
bob a9; 
bob a10; 
bob a11; 
bob a12; 

bob mover; 

void setup () {
  size(600, 600); 

  a1 = new bob(0, 0, 0, 0); 
  a2 = new bob(0, 0, 30, 0); 
  a3 = new bob(0, 0, 60, 0); 
  a4 = new bob(0, 0, 90, 0); 
  a5 = new bob(0, 0, 120, 0); 
  a6 = new bob(0, 0, 150, 0); 
  a7 = new bob(0, 0, 180, 0); 
  a8 = new bob(0, 0, 210, 0); 
  a9 = new bob(0, 0, 240, 0); 
  a10 = new bob(0, 0, 270, 0); 
  a11= new bob(0, 0, 300, 0); 
  a12 = new bob(0, 0, 330, 0);

  mover = new bob(0, 0, 0, color(255, 255, 0));
}

void draw() {

  background (255); 
  mover.rot += 1; 

  if (mover.overlaps(a1)) {
    background (180);
  } else if 
    (mover.overlaps(a2)) {
    background (40);
  } else if 
    (mover.overlaps(a3)) {
    background (20);
  }

  a1.display(); 
  a2.display();
  a3.display(); 
  a4.display(); 
  a5.display();
  a6.display(); 
  a7.display(); 
  a8.display();
  a9.display(); 
  a10.display(); 
  a11.display();
  a12.display(); 

  mover.display();

}

```

And my class:

```auto
class bob {

  PVector loc; //location 
  float l = 100; // length
  float rot; // rotate
  float r=40; // radius
  color c = color(0, 0, 0); 
  float a = 0; 

  bob (float tempX, float tempY, float tempRot, color tempC) {

    loc=new PVector(0, 0); 

    loc.x = tempX; 
    loc.y = tempY; 

    rot = tempRot; 
    c = tempC; 

    loc.x = loc.x+l*sin(a); 
    loc.y = loc.x+l*cos(a);
  }

  boolean overlaps (bob other) {
    float d = dist (loc.x, loc.y, other.loc.x, other.loc.y); 
    if (d < 35) {
      return true;
    } else {
      return false;
    }
  }

  void display() {

    fill (c); 

    pushMatrix();
    translate (width/2, height/2); 
    rotate(radians(rot)); 
   ellipse (loc.x,loc.y,r,r); 

    popMatrix();
  }
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [November 30, 2022, 12:42am UTC](https://discourse.processing.org/t/spin-the-bottle-360-degrees-with-pvector/39872/7 "2022-11-30T00:42:04Z")

</div>

Hello @acousticer,

> [@glv](#):
>
> You need to compare the two locations directly.

A transformation does not change the value of variables and only transforms them:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/0/9/09c11450950b6af6aebb07810553b772af2ea91f.png)

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/b/9/b97f5c572bc9fd579be5722aa1e36ecc148be1fa.png)

Changes made to get this working:

```auto
// draw()
 translate (width/2, height/2); 
 mover.a += radians(1);

```

```auto
// class
  void display() 
    {
    fill (c); 
    loc.x = l*sin(a); 
    loc.y = l*cos(a);
    ellipse (loc.x,loc.y, r, r); 
    }

```

You can complete the missing code.

References:

> **[2D Transformations](https://processing.org/tutorials/transform2d/)**
>
> Learn how to translate, rotate, and scale shapes using 2D transformations.

`:)`
