# I don't understand modelX/modelY

**URL:** <https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470>\
**Category:** Coding Questions\
**Created:** [December 13, 2023, 11:22pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470 "2023-12-13T23:22:50Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![PianoMastR64](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/pianomastr64/32/19124_2.png) [@PianoMastR64](https://discourse.processing.org/u/PianoMastR64)\
**Post date:** [December 13, 2023, 11:22pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/1 "2023-12-13T23:22:50Z")

</div>

```auto
    @Override
    public void settings() {
        size(800, 800, P3D);
        smooth(8);
    }
    
    
    @Override
    public void setup() {
    }
    
    @Override
    public void draw() {
        background(0);
        
        translate(width / 2f, height / 2f);
        
        // Print world coordinates
        if(frameCount % 20 == 0) {
            System.out.println(modelX(400, 400, 0) + ", " + modelY(400, 400, 0));
        }
    }

```

After translating by width/2 and height/2, the model origin should be in the center of the 800x800 screen. So, when I convert point (400, 400) in screen space to model space, I should expect to see (0, 0) as the output. But instead I see (800, 800). What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 13, 2023, 11:31pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/2 "2023-12-13T23:31:54Z")

</div>

modelX just gives you the point in space including the translation before

(The point is calculated from the initial origin)

So its 400 + 400 in your example

One 400 is from translate() command and one 400 from modelX() command itself

Normally we call modelX with (0,0,0)

---

<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:** [December 14, 2023, 11:40am UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/3 "2023-12-14T11:40:39Z")

</div>

Hello @PianoMastR64,

Read the reference carefully:

> **[modelX() / Reference](https://processing.org/reference/modelX_.html)**
>
> Returns the three-dimensional X, Y, Z position in model space. This returns the X value for a given coordinate based on the current set of transformations (scale, rotate, translate, etc.) The X value …

May have to read a few times to digest this.

Consider _model space_ as the co-ordinate system of the sketch window with the origin (0, 0, 0) in the upper left.

`:)`

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 14, 2023, 1:09pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/4 "2023-12-14T13:09:38Z")

</div>

And later you need modelZ as well

(Other than screenX and screenY)

---

<div class="post-metadata">

**Author:** ![PianoMastR64](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/pianomastr64/32/19124_2.png) [@PianoMastR64](https://discourse.processing.org/u/PianoMastR64)\
**Post date:** [December 15, 2023, 6:48pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/5 "2023-12-15T18:48:22Z")

</div>

Ok, I understand now. So, what’s the best way to get model coordinates based on given screen coordinates?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 15, 2023, 8:38pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/6 "2023-12-15T20:38:38Z")

</div>

What is your context and your goal?

What do you want to achieve?

---

<div class="post-metadata">

**Author:** ![PianoMastR64](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/pianomastr64/32/19124_2.png) [@PianoMastR64](https://discourse.processing.org/u/PianoMastR64)\
**Post date:** [December 16, 2023, 6:08am UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/7 "2023-12-16T06:08:42Z")

</div>

No specific goal other than that I want to figure out where the mouse would be if it were expressed in model coordinates. It would be useful functionality in a handful of scenarios.

I figured out how to do it for `JAVA2D` and `P2D`, but things get a little weird with `P3D`.

```auto
    @Override
    public void settings() {
        size(800, 800);
    }

    @Override
    public void draw() {
        background(0);
        
        translate(50, 50);
        rotate(PI / 8f);
        
        PVector modelMouse = ModelMouse(this);
        
        circle(mouseX, mouseY, 10);
        circle(modelMouse.x, modelMouse.y, 10);
    }
    
    public static PVector ModelMouse(PApplet app) {
        PMatrix currentMatrix = app.getMatrix();
        currentMatrix.invert();
        return currentMatrix.mult(new PVector(app.mouseX, app.mouseY, 0), null);
    }

```

Here, the first circle is drawn where you’d expect it to be, given the transformations. The second circle is drawn at the mouse’s location.

When you switch to `size(800, 800, P3D)`, the first circle is the same. But the second circle seems to be in the middle of the screen. I’ve figured out that you can compensate for that by subtracting half a screen from the mouse before doing the reverse transformation.

```auto
    public static PVector ModelMouse(PApplet app) {
        PMatrix currentMatrix = app.getMatrix();
        currentMatrix.invert();
        PVector mouse = new PVector(app.mouseX, app.mouseY, 0);
        if(app.g.is3D()) {
            mouse.x -= app.width / 2f;
            mouse.y -= app.height / 2f;
        }
        return currentMatrix.mult(mouse, null);
    }

```

Then I can also draw the sphere at the mouse like this. The method is generalized so I can add it to my custom PAppletUtility class

```auto
        push();
        translate(modelMouse.x, modelMouse.y);
        sphere(100);
        pop();

```

So I guess I got it. Took a hot annoying sec to figure out. I don’t know if this is the best way though or why I need to do that weird compensation for `P3D`.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 16, 2023, 6:28am UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/8 "2023-12-16T06:28:32Z")

</div>

Maybe in 2D the center is upper left corner and in 3D as  
well, but the internal camera position is different

---

<div class="post-metadata">

**Author:** ![PianoMastR64](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/pianomastr64/32/19124_2.png) [@PianoMastR64](https://discourse.processing.org/u/PianoMastR64)\
**Post date:** [December 16, 2023, 6:35am UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/9 "2023-12-16T06:35:41Z")

</div>

Idk. Drawing stuff at 0, 0, 0 in `P3D` does put it in the top left corner. Maybe I’ll investigate that someday.

You would think `modelX/Y()` would do what I thought it did because `screenX/Y()` gives that same information but in reverse. Instead, `modelX/Y()` seems to be the exact same thing as `screenX/Y()` other than taking an extra argument `z`. I’m still confused about that, and trying to understand.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 16, 2023, 12:18pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/10 "2023-12-16T12:18:12Z")

</div>

in your example, modelX/modelY doesn’t occur?

in fact, modelX/modelY has nothing to do with the mouse.

- modelX/modelY/modelZ(!) gives you a point in 3D space, including translate and rotate before it. Useful for special purposes, nothing to do with the mouse (or the screen). modelX/modelY without modelZ doesn’t make sense btw.
- screenX/screenY gives you a 2D screen pos from a 3D pos. So when you want to match a 3D pos with the mouse, use this.
- The opposite of screenX/screenY (receiving a 3D point from a 2D screen point) doesn’t exist, It wouldn’t be possible, because of the 3D perspective there is a lack of information, you can have endless 3D number of 3D points that all have the same screenX/screenY.

Of course the view in 3D is totally different from 2D since we have a perspective and things shrink in the background.

Let’s ask one of the gurus, like @quark what they think of it

---

<div class="post-metadata">

**Author:** ![PianoMastR64](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/pianomastr64/32/19124_2.png) [@PianoMastR64](https://discourse.processing.org/u/PianoMastR64)\
**Post date:** [December 16, 2023, 5:23pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/11 "2023-12-16T17:23:42Z")

</div>

> in your example, modelX/modelY doesn’t occur?

Turns out I didn’t need it for my purpose. I was just entirely too convinced it’s what I needed.

> The opposite of screenX/screenY (receiving a 3D point from a 2D screen point) doesn’t exist, It wouldn’t be possible, because of the 3D perspective there is a lack of information, you can have endless 3D number of 3D points that all have the same screenX/screenY.

Not sure why I didn’t consider this. My example solves my problem perfectly. …as long as the point in model space is at exactly 0 on the z axis. Any different value throws it off. Negative values shift it inward, and positive outward. Even if I compensate for that by making sure the 3D coordinate always coincides with the mouse, there’s still an infinite line of variability which probably depends on the camera position or something.

When I get around to it, I’ll have a big think on how best to account for this.

One example for why I might need this is if I want to check which object the mouse is hovering over so I can move it around. For that, I actually don’t even need a point, but more of a vector.

Another example is to click somewhere on the screen and spawn an object, for which I will need a point. I’ll just have to find some way of deciding which point on that line matters to me in that moment.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 16, 2023, 7:31pm UTC](https://discourse.processing.org/t/i-dont-understand-modelx-modely/43470/12 "2023-12-16T19:31:17Z")

</div>

hello,

> [@PianoMastR64](#):
>
> why I might need this is if I want to check which object the mouse is hovering over so I can move it around

That’s a good point (no pun intended). Here you can use screenX and screenY and compare them to the mouse pos.  
Another method is an off-screen PGraphics, like point B here: [Selecting & Moving 3D Primitives - urgent - #3 by Chrisir](https://discourse.processing.org/t/selecting-moving-3d-primitives-urgent/14702/3)

> [@PianoMastR64](#):
>
> Another example is to click somewhere on the screen and spawn an object,

Another very good point!

In fact I asked this here: [Pro-Question: place a point in 3D with mouse](https://discourse.processing.org/t/pro-question-place-a-point-in-3d-with-mouse/6664) and  
here [P3D Formula : opposite of screenX and screenY is ...?](https://discourse.processing.org/t/p3d-formula-opposite-of-screenx-and-screeny-is/10121)

I still think this is solvable.

For example when you place a new cube, you could assume the same Z value as the previous cube. Then the new x and y should be calculable.

Chrisir
