# Local to global positions

**URL:** <https://discourse.processing.org/t/local-to-global-positions/29333>\
**Category:** Coding Questions\
**Created:** [April 13, 2021, 1:54pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333 "2021-04-13T13:54:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![saul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/saul/32/12811_2.png) [@saul](https://discourse.processing.org/u/saul)\
**Post date:** [April 13, 2021, 1:54pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333/1 "2021-04-13T13:54:54Z")

</div>

Hi there;

Been dipping my toe in a little p5 and ran into what might be a common problem with what I hope is a common answer (although I couldn’t find one)

I have a sketch that creates a secondary canvas and centers it in the primary canvas within the secondary canvas I have a number of class based objects that should react to the distance from their mouse - but all the positioning seems to be based off the origin of the primary canvas. Hopefully my simplified example does a better job of explaining this, the red dot is in the same position within the primary canvas that the white dot is within the secondary - I know I need to use a custom distance calculation that somehow takes into consideration the origin of the secondary canvas - that’s as far as I’ve gotten - any guidance would be really appreciated.

```auto
let pg;
let dot;
let d;

function setup() {
  createCanvas(300, 300);
  background(0);
  pg = createGraphics(100, 100);
  pg.background(80);
  pg.noStroke();
  d = new Dot(pg, 25, 25);
  fill(255,0,0);
  ellipse(25,25,10);
}

function draw() {
  d.display();
  d.update(mouseX, mouseY);
  imageMode(CENTER);
  image(pg, width/2, height/2);
}

class Dot {
  constructor(_canvas, _x, _y) {
    this.canvas = _canvas;
    this.x = _x;
    this.y = _y;
    this.c = 255;
  }
  display() {
    this.canvas.fill(this.c);
    this.canvas.ellipse(this.x, this.y, 10);
  }
  update(mX, mY) {
    let ds = dist(mX, mY, this.x, this.y);
    console.log(ds);
    if (ds < 10) {
      this.c = 50;
    }else{
      this.c = 255;
    }
  }
}

```

---

<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:** [April 13, 2021, 2:04pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333/2 "2021-04-13T14:04:32Z")

</div>

Hi! Welcome to the forum.

I quite don’t get what you mean - do you want to make the color react to the mouse close to the white circle instead of the red one? If so I guess you need a separate set of x/y in the Dot class to store the offset of the canvas, and add them when you calculate the distance.

Also ellipse/circle takes diameter not radius, just to let you know!

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [April 13, 2021, 2:10pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333/3 "2021-04-13T14:10:42Z")

</div>

Store the `x` and `y` offset coordinates of the origin of the secondary canvas relative to the primary canvas as attributes in an object that relates to the secondary canvas. Then to convert `x` and `y` coordinates of mouse clicks into secondary canvas coordinates, subtract the `x` and `y` coordinates of the stored offsets from the `x` and `y` coordinates of the mouse clicks. So, if the origin of the secondary canvas is at `100, 100`, and the mouse is clicked at `200, 300` on the primary canvas, the subtraction gives us `100, 200`.

---

<div class="post-metadata">

**Author:** ![saul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/saul/32/12811_2.png) [@saul](https://discourse.processing.org/u/saul)\
**Post date:** [April 13, 2021, 2:18pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333/4 "2021-04-13T14:18:21Z")

</div>

So assuming that the primary canvas is windowWidth and windowHeight and the secondary canvas is centered storing all that initial math is a great idea - i was just really hoping for some kind of global to local math I didn’t have to write - so such luck huh?

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [April 13, 2021, 2:26pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333/5 "2021-04-13T14:26:51Z")

</div>

Create a method within the class that contains or references the secondary canvas to do the math. It should just get the coordinates of the mouse click, do the subtraction using the stored origin of the secondary canvas, and return the resulting converted coordinates. With the details handled by that method whenever the mouse is clicked, writing the rest of the code for the script should become easier. The idea is to contain the messy stuff within the method, then to use it as a convenience for writing the rest of the script.

_EDIT (2x on April 13, 2021):_

We could do this type of thing with any instance of an object that we can display in the sketch, whether or not it involves a secondary canvas.

Below is a simple example, wherein the origin of the displayed object is the center of that object. The object displays the mouse position relative to its own origin. In this case, the math is not very complicated, and is handled by the `report_mouse_position()` method. We could do the same with a secondary canvas.

```auto
let p;
function setup() {
  createCanvas(400, 400);
  textAlign(CENTER, CENTER);
  textSize(32);
  p = new Pancake(200, 200, 255);
}

function draw() {
   background(255);
   p.display();
}

class Pancake {
  constructor(x, y, diam) {
    this.x = x;
    this.y = y;
    this.diam = diam;
  }
  display() {
    circle(this.x, this.y, this.diam);
    let mp = this.report_mouse_position();
    text("" + mp[0] + ", " + mp[1], this.x, this.y);
  }
  report_mouse_position() {
    return [mouseX - this.x, mouseY - this.y];
  }
}

```

![pancake](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/2/26b8bc221385a20b9a230bb6b17f852a2d47cef2.png)

---

<div class="post-metadata">

**Author:** ![saul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/saul/32/12811_2.png) [@saul](https://discourse.processing.org/u/saul)\
**Post date:** [April 13, 2021, 6:29pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333/6 "2021-04-13T18:29:33Z")

</div>

This really helps - curious is there a benefit to calling **report\_mouse\_position** from within display rather than having a separate call to it within Draw?

> [@javagar](#):
>
> ```auto
> display() {
> circle(this.x, this.y, this.diam);
> let mp = this.report_mouse_position();
> }
> report_mouse_position() {
> return [mouseX - this.x, mouseY - this.y];
> }
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [April 13, 2021, 7:09pm UTC](https://discourse.processing.org/t/local-to-global-positions/29333/7 "2021-04-13T19:09:20Z")

</div>

> [@saul](#):
>
> … is there a benefit to calling **report\_mouse\_position** from within display rather than having a separate call to it within Draw?

Either way is fine. It is just a matter of convenience. If you would like to use the information returned by the `report_mouse_position()` method within the `draw()` function, you should call it from there. Otherwise, it might be more convenient for you to have the `display()` method do that work for you. In this particular situation, it doesn’t make much difference. However, in a case where several different methods must be called to gather all the information together to display or perform some other operation on an object, it would be convenient to have the `display()` or other pertinent method belonging to the object do the work of gathering together and processing that information.
