# Aiming marbles away from a central point

**URL:** <https://discourse.processing.org/t/aiming-marbles-away-from-a-central-point/28535>\
**Category:** Coding Questions\
**Created:** [March 14, 2021, 5:01pm UTC](https://discourse.processing.org/t/aiming-marbles-away-from-a-central-point/28535 "2021-03-14T17:01:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ottenm](https://avatars.discourse-cdn.com/v4/letter/o/f08c70/32.png) [@ottenm](https://discourse.processing.org/u/ottenm)\
**Post date:** [March 14, 2021, 5:01pm UTC](https://discourse.processing.org/t/aiming-marbles-away-from-a-central-point/28535/1 "2021-03-14T17:01:00Z")

</div>

I have a sketch that simulates marbles bumping into each other. Each marble has one PVector for ‘location’ and another one for ‘velocity’. location.add(velocity) moves the marble to it’s next location, slowly for small velocities, quickly for larger ones.

I’d like to create a small group of marbles clustering around some random point, with random initial velocities but all pointing straight out/away from the middle of the cluster.

Below are the main pieces pulled out of the rest of the sketch. It just places the marbles but doesn’t move them around, decrease their velocities, etc…

Any help setting the velocities to point outward from ‘r’ would be huge!!

```auto
class MovingPoint {
  PVector location, velocity;
  MovingPoint(float x, float y, float xv, float yv) {
    location = new PVector(x, y);
    velocity = new PVector(xv, yv);
  }
}

MovingPoint [] points;

void setup() {
  size(800, 600);
  ellipseMode(CENTER);
  points = new MovingPoint[10];
  for (int i=0; i<10; i++)
    points[i] = new MovingPoint(0, 0, 0, 0);
  initializePoints();
}

void initializePoints() {
  // pick a semi-random point as the center
  PVector r = new PVector(random(200, 600), random(200, 400));
  for (int i=0; i<10; i++) {
    points[i].location.x = r.x + random(-50, 50);
    points[i].location.y = r.y + random(-50, 50);
    // how to set the velocities pointing out/away from 'r'?  
  }
}

void draw() {
  background(225);
  stroke(0);
  fill(0);
  for (int i=0; i<10; i++)
    ellipse(points[i].location.x, points[i].location.y, 10, 10);
}

void mouseClicked() {
  initializePoints();
}

```

---

<div class="post-metadata">

**Author:** ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)\
**Post date:** [March 14, 2021, 6:21pm UTC](https://discourse.processing.org/t/aiming-marbles-away-from-a-central-point/28535/2 "2021-03-14T18:21:46Z")

</div>

Hi! If you have no idea what to start with, I recommend you to read Dan’s book or watch his videos to get familiarized with vectors  
[https://natureofcode.com/book/chapter-1-vectors/](https://natureofcode.com/book/chapter-1-vectors/)

[![](https://img.youtube.com/vi/mWJkvxQXIa8/hqdefault.jpg "1.1: Vectors - The Nature of Code") ](https://www.youtube.com/watch?v=mWJkvxQXIa8)

tip: how you initialize the point will end up with points forming a square (you will find it if you increase the number of points). If you want a circular distribution, check out `random2D`, which returns a vector with a random angle and a unit length. Then you can scale the vector with a random value.

> **[random2D() / Reference](https://processing.org/reference/pvector_random2d_)**
>
> Returns a new 2D unit vector with a random direction. If you pass in this as an argument, it will use the PApplet's random number generator.

---

<div class="post-metadata">

**Author:** ![ottenm](https://avatars.discourse-cdn.com/v4/letter/o/f08c70/32.png) [@ottenm](https://discourse.processing.org/u/ottenm)\
**Post date:** [March 15, 2021, 3:25am UTC](https://discourse.processing.org/t/aiming-marbles-away-from-a-central-point/28535/3 "2021-03-15T03:25:32Z")

</div>

Thanks a ton micuat!

I ended up using polar coordinates to aim the marbles straight out from the center. Here’s the rework in case it helps anyone else-

```auto
class MovingPoint {
  PVector location, velocity;
  MovingPoint(float x, float y, float xv, float yv) {
    location = new PVector(x, y);
    velocity = new PVector(xv, yv);
  }
}

final int NUM_POINTS = 10;
MovingPoint [] points;
PVector center;

void setup() {  
  size(800, 600);
  ellipseMode(CENTER);
  points = new MovingPoint[NUM_POINTS];
  center = new PVector();
  for (int i=0; i<NUM_POINTS; i++)
    points[i] = new MovingPoint(0, 0, 0, 0);
  initializePoints();
}

void initializePoints() {
  float radius = 50; // radius from center to marbles
  float degrees = 270; // top
  float dx = 360.0 / NUM_POINTS;
  // pick a semi-random point as the center
  center = new PVector(random(200, 600), random(200, 400));
  for (int i=0; i< NUM_POINTS; i++, degrees+=dx) {
    float x = center.x + radius * cos(radians(degrees));
    float y = center.y + radius * sin(radians(degrees));
    points[i].location.x = x; 
    points[i].location.y = y;   
    // calculate the point twice as far out as this one (going straight out)
    // ... and set the velocity equal to the difference
    // (so one "location.add(velocity)" moves this marble twice as far out)
    points[i].velocity.x = (center.x + radius * 2 * cos(radians(degrees))) - x;
    points[i].velocity.y = (center.y + radius * 2 * sin(radians(degrees))) - y;
  }
}

void draw() {
  if (millis() < 1000)
    ((java.awt.Canvas) surface.getNative()).requestFocus();
  background(225);
  stroke(255, 0, 50);
  fill(255, 0, 50);
  ellipse(center.x, center.y, 5, 5);
  stroke(0);
  fill(0);
  for (int i=0; i<NUM_POINTS; i++) {
    MovingPoint p = points[i];
    ellipse(p.location.x, p.location.y, 10, 10);
    // add one pass at the velocity to see where the marble is headed
    line(p.location.x, p.location.y, p.location.x + p.velocity.x, p.location.y + p.velocity.y);
  }
}

void mouseClicked() {
  initializePoints();
}

```

---

<div class="post-metadata">

**Author:** ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)\
**Post date:** [March 15, 2021, 11:28am UTC](https://discourse.processing.org/t/aiming-marbles-away-from-a-central-point/28535/4 "2021-03-15T11:28:23Z")

</div>

yay! This is the way that is similar to `random2D` and makes a nice distribution too. You can also randomize the `radius` or you don’t have to.

By the way, if you do a bit more of math, you notice that the velocity is actually

```auto
points[i].velocity.x = radius * cos(radians(degrees));
points[i].velocity.y = radius * sin(radians(degrees));

```

but either way works 🙂 The repulsion force (this case velocity) is a difference between the two points (where the force is applied - where the center is) so actually the position of `PVector center` doesn’t affect the velocity and only the offset (this case `cos/sin * radius` or in the previous case `random(-50,50)`) matters.
