# Relatives and global positioning

**URL:** https://discourse.processing.org/t/relatives-and-global-positioning/47006
**Category:** Coding Questions
**Created:** [August 22, 2025, 1:30pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006 "2025-08-22T13:30:22Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![EricRogerGarcia](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ericrogergarcia/32/21029_2.png) [@EricRogerGarcia](https://discourse.processing.org/u/EricRogerGarcia)
#### Post date: [August 22, 2025, 1:30pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/1 "2025-08-22T13:30:22Z")

</div>

If we don’t use scaling, it works well but there…  
it doesn’t work at all… and I really don’t find why.

If you know it…

thank you VERY much in advance !!!

[The sketch is here !](https://openprocessing.org/sketch/2705852)

Otherwise, Openprocessing indicates an error that I don’t have at all on my computer when I run this sketch!

**N.B.** same sketch in Processing :

[transform\_java](http://ericrogergarcia.legtux.org/site/file/source/processing/pstarengine/transform_java.zip)

---

<div class="post-metadata">

### Author: ![davepagurek](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/davepagurek/32/17535_2.png) [@davepagurek](https://discourse.processing.org/u/davepagurek)
#### Post date: [August 22, 2025, 2:07pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/2 "2025-08-22T14:07:05Z")

</div>

Hi! I think I can see two problems in `runOutMatrix`:

- I think you aren’t accumulating the parent’s position, only its scale. The child’s total position should be `createVector(parentX + parentScale * childX, parentY + parentScale + childY)`, as the parent’s scale also applies to the position relative to the parent.
- It looks like you’re only accumulating position/scale from the direct parent, but that parent may also have a parent. Likely you will need to make your function recursive to account for that.

---

<div class="post-metadata">

### Author: ![davepagurek](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/davepagurek/32/17535_2.png) [@davepagurek](https://discourse.processing.org/u/davepagurek)
#### Post date: [August 22, 2025, 2:36pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/3 "2025-08-22T14:36:53Z")

</div>

Also one thing that might be of interest is the `DOMMatrixReadOnly` JavaScript class: [DOMMatrixReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrixReadOnly) It lets you keep track of a transform with multiple nested translations and scales and will also let you extend your code to include rotations too if you need.

It would let you do something like this:

```auto
class Thing {
  globalTransform() {
    let parentMatrix = new DOMMatrixReadOnly()
    if (this.parent) {
      parentMatrix = this.parent.globalTransform()
    }
    return parentMatrix
      .translate(this.position.x, this.position.y)
      .scale(this.scale)
  }

  runOutMatrix() {
    push()
    const m = this.globalMatrix()
    applyMatrix(m.a, m.b, m.c, m.d, m.e, m.f)
    // draw something here
    pop()

    for (const child of this.children) {
      child.runOutMatrix()
    }
  }

```

---

<div class="post-metadata">

### Author: ![EricRogerGarcia](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ericrogergarcia/32/21029_2.png) [@EricRogerGarcia](https://discourse.processing.org/u/EricRogerGarcia)
#### Post date: [August 22, 2025, 8:42pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/4 "2025-08-22T20:42:08Z")

</div>

THANK you **beaucoup** … (a lot) 🙃

It looks super interesting !!!

Yes indeed, taking care of the rotation is my next goal 🐣 !

I will watch this very closely as soon as possible (I can’t wait!)… I have to take care of something else by Saturday evening - Sunday! 😥

your webpage [https://www.davepagurek.com/](https://www.davepagurek.com/) seems very interesting too (😢 I’m going to come back to it later !)

---

<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: [August 24, 2025, 3:38pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/5 "2025-08-24T15:38:39Z")

</div>

Hello @EricRogerGarcia,

I did some more digging:

- [Converting webgl 3d coordinates to 2d screen coordinates (p5.js) - Processing 2.x and 3.x Forum](https://forum.processing.org/two/discussion/17715/converting-webgl-3d-coordinates-to-2d-screen-coordinates-p5-js.html)
- [Add screenX, screenY and screenZ · Issue #1553 · processing/p5.js · GitHub](https://github.com/processing/p5.js/issues/1553)
- That is just scratching the surface!

There may be something in there that can help with p5.js!

`:)`

---

<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: [September 9, 2025, 3:46pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/6 "2025-09-09T15:46:02Z")

</div>

Related:

> [@Relative and global coordinates](https://discourse.processing.org/t/relative-and-global-coordinates/46992/5):
>
> see also [screenX screenY equivalent in p5.js - #5 by bohnacker](https://discourse.processing.org/t/screenx-screeny-equivalent-in-p5-js/10581/5)

---

<div class="post-metadata">

### Author: ![EricRogerGarcia](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ericrogergarcia/32/21029_2.png) [@EricRogerGarcia](https://discourse.processing.org/u/EricRogerGarcia)
#### Post date: [September 23, 2025, 3:47pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/7 "2025-09-23T15:47:13Z")

</div>

There, it works!

(I didn’t have much time….)  
(In Processing because I prefer Java for thinking!)

I will take care of the rotation issue now.

N.B. I absolutely need to solve this because the upcoming collision management will have to be done outside of the transformations applied to the objects for their display

P.S. I will also look at everything you told me about to learn new things!

thanks a lot ! 😁

 ![transforms-java](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/f/a/fa6280143fb79ae9a6c1951b29d67f9073cf92a0.jpeg)

```auto
Thing things;

void setup() {
  size(1000, 600);
  things=new Thing(width/2, height/2, 0.001);
  for (int i=0; i<10; i++) {
    Thing newThing=new Thing(random(width)-width/2, random(height)-height/2, random(1, 4));
    things.addChild(newThing);
    for (int j=0; j<5; j++) {
      newThing.addChild(new Thing(random(width/2)-width/4, random(height/2)-height/4, random(1,4)));
    }
  }
  frameRate(20);
}

void draw() {
  background(200);
  things.run();
  things.scale += .003;
}

class Thing {
  PVector position, globalPosition;
  float scale, globalScale;
  Thing parent;
  ArrayList<Thing> children;

  Thing(float x, float y, float scale) {
    this.position=new PVector(x, y);
    this.globalPosition=this.position.copy(); // globalPosition : Vector
    this.scale=scale; // scale : Number
    this.globalScale=scale;
    parent=null; // parent : Thing
    children = new ArrayList<>(); // children : Array<Thing>
  }

  void addChild(Thing child) { // child : Thing
    this.children.add(child);
    child.parent = this;
  }

  void runInMatrix() {
    push();
    translate(this.position.x, this.position.y); // translate first so position / parent coordinate system
    scale(this.scale); // scale then: display in the scale of the parent * scale of the object

    // display
    if (parent==null) {
      fill(0, 0, 0);
    } else {
      fill(255, 0, 0); // red
    }
    circle(0, 0, 20);
    
    for (Thing child : this.children) {
      child.runInMatrix();
    }

    pop();
  }

  void runOutMatrix() {
    if (this.parent!=null) { // not the root Thing
      this.globalScale = this.parent.globalScale * this.scale; // to show the object
      this.globalPosition=this.parent.globalPosition.copy().add(position.copy().mult(parent.globalScale));
    } else {
      globalScale=scale;
    }

    //display
    fill(0, 255, 0); // green
    circle(this.globalPosition.x, this.globalPosition.y, 10*globalScale);

    for (Thing child : this.children) {
      child.runOutMatrix();
    }
  }

  void run() {
    this.runInMatrix();
    this.runOutMatrix();
  }
}

```

---

<div class="post-metadata">

### Author: ![EricRogerGarcia](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ericrogergarcia/32/21029_2.png) [@EricRogerGarcia](https://discourse.processing.org/u/EricRogerGarcia)
#### Post date: [September 24, 2025, 10:50am UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/8 "2025-09-24T10:50:30Z")

</div>

et voilà !!!

 ![transforms-java](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/f/d/fd1488fc6ed40ed37e361e178b119acf7907557f.jpeg)

```auto
Thing things;

void setup() {
  size(1000, 600);
  things=new Thing(width/2, height/2, 40, 40, 0.6, 2)
      .setRotationVelocity(0.01);
  for (int i=0; i<10; i++) {
    Thing newThing=new Thing(random(width)-width/2, random(height)-height/2, 40, 40, random(0, 2), random(1, 7))
      .setRotationVelocity(0.02);
    things.addChild(newThing);
    for (int j=0; j<5; j++) {
      newThing.addChild(new Thing(random(width/2)-width/4, random(height/2)-height/4, 40, 40, random(0, 2), random(1, 4)));
    }
  }
  frameRate(20);
  rectMode(CENTER);
}

void draw() {
  background(200);
  things.run();
}

class Thing {
  PVector position, globalPosition;
  float scale, globalScale;
  Thing parent;
  ArrayList<Thing> children;
  float twidth, theight, rotation;
  float globalRotation;
  float rotationVelocity=0;

  Thing(float x, float y, float w, float h, float scale, float r) {
    this.position=new PVector(x, y);
    this.globalPosition=this.position; // globalPosition : Vector
    this.scale=scale; // scale : Number
    this.globalScale=scale;
    parent=null; // parent : Thing
    children = new ArrayList<>(); // children : Array<Thing>
    twidth = w;
    theight = h;
    rotation=r;
  }

  Thing setRotationVelocity(float rv) {
    rotationVelocity=rv;
    return this;
  }

  void runRotation() {
    rotation+=rotationVelocity;
    for (Thing child : this.children) {
      child.runRotation();
    }
  }

  void addChild(Thing child) { // child : Thing
    this.children.add(child);
    child.parent = this;
  }

  void runInMatrix() {
    push();
    translate(this.position.x, this.position.y); // translate first so position / parent coordinate system
    scale(this.scale); // scale then: display in the scale of the parent * scale of the object
    rotate(rotation);

    // display
    if (parent==null) {
      fill(0, 0, 0);
    } else {
      fill(255, 0, 0); // red
    }
    rect(0, 0, twidth, theight);

    for (Thing child : this.children) {
      child.runInMatrix();
    }

    pop();
  }

  void runOutMatrix() {
    if (this.parent!=null) { // not the root Thing
      this.globalScale = this.parent.globalScale * this.scale; // to show the object
      globalRotation=parent.globalRotation + this.rotation;
      PVector positionWithScale = position.copy().mult(parent.globalScale);
      globalPosition=parent.globalPosition.copy().add(positionWithScale.setHeading(position.heading()+parent.globalRotation));
    } else { // root Thing
      globalScale=scale;
      globalRotation=rotation;
    }

    //display
    fill(0, 255, 0); // green
    resetMatrix();
    translate(globalPosition.x, globalPosition.y);
    rotate(globalRotation);
    rect(0, 0, twidth*globalScale/2, theight*globalScale/2);

    for (Thing child : this.children) {
      child.runOutMatrix();
    }
  }

  void run() {
    runRotation();
    this.runInMatrix();
    this.runOutMatrix();
  }
}

```

---

<div class="post-metadata">

### Author: ![EricRogerGarcia](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ericrogergarcia/32/21029_2.png) [@EricRogerGarcia](https://discourse.processing.org/u/EricRogerGarcia)
#### Post date: [September 26, 2025, 5:56pm UTC](https://discourse.processing.org/t/relatives-and-global-positioning/47006/9 "2025-09-26T17:56:04Z")

</div>

[See here in P5js](https://editor.p5js.org/EricRogerGarcia/sketches/bGRy1APQ4)
