<p>Not sure if Ogre does it implicitely, but using a 4x4 matrix to transform a 3D point to get the correct 2D coordinates (as it would be rendered with the same matrix),  requires a transition from homogeneous coordinates by dividing the result by w. </p>

<p>In other words, you must multiply the matrix by a 4-component vector (x,y,z,1.0f) instead of a 3-component vector. And then the resulting vector will look like (X,Y,Z,W) and you need to divide by W to get the position like it would be rendered. </p>

<p>Like this: </p>

<pre><code>// Transform world coordinates.
Ogre::Vector4 transformedWorldPosition = worldViewProjection * Ogre::Vector4(worldPosition,1.0);

//Divide by w 
transformedWorldPosition = transformedWorldPosition / transformedWorldPosition.w; 

// Calculate screen coordinates from world coordinates.
Ogre::Vector2 screenPosition;
screenPosition.x = (int) ( ( ( transformedWorldPosition.x + 1 ) / 2.0 ) * screenRes.width + 0.5 );
screenPosition.y = (int) ( ( ( 1 - transformedWorldPosition.y ) / 2.0 ) * screenRes.height + 0.5 );
</code></pre>

CC BY-SA 3.0
2018-02-17T16:21:31.047Z
2018-02-17T16:21:31.047Z
unknown
<p>From what I can see, it looks like screenPosition.x is in some sort of screen space and screenPositionX is in terms of the actual pixel buffer in units of pixels. My guess is that cropImage wants its inputs in units of pixels but when you calculate min_x, min_y, ... you are using screenPosition.x when you should really be using screenPositionX. Also, where does radius come from? Is it in world space, screen space, or pixel buffer space?</p>

<p>Regardless of whether or not that fixes your problem, try to be more explicit in the future about your variables names to keep track of which space/units you are in. Having a screenPosition.x and a screenPositionX which refer to different things is generally a bad idea.</p>

CC BY-SA 3.0
2017-12-19T11:52:28.217Z
the radius is pixel buffer space, screenPosition.x is screenspace, and screenPositionX is in actual pixel buffer. I still gets wrong cropped rectangle. Thanks
Andre Ahmed
CC BY-SA 3.0
2017-12-19T11:59:41.200Z
I have edited the post.. still I get wrong cropped image, out of bounds exception
Andre Ahmed
CC BY-SA 3.0
2017-12-19T18:13:12.990Z
Which piece of code gives the out of bounds exception?
Chuck
CC BY-SA 3.0
2017-12-19T20:35:16.427Z
Ogre::Image *out = cropImage(img,  min_x, min_y,  max_x,  max_y);
Andre Ahmed
CC BY-SA 3.0
2017-12-21T07:09:05.123Z
This is a longshot but maybe you need to clamp the max value to cameraRes - 1 because accessing cameraRes on a zero indexed array would be out of bounds.
Chuck
CC BY-SA 3.0
2017-12-18T22:39:35.610Z
2017-12-18T22:39:35.610Z
Chuck
<p>I'm trying to get a 2D screen position so I unproject a point from 3D into 2D screen coordinates by that following function:</p>

<pre><code>Ogre::Vector2 SpaceTransformHelper::convertWorldToScreenPosition( const Ogre::Vector3&amp; worldPosition )
{
    Stages::AStage* currStage = Stages::StageManager::getSingleton()-&gt;getActiveStage();
    Core::Resolution screenRes = Core::EnvironmentInformation::getSingleton()-&gt;getScreenResolution();

    // Get worldviewprojection from camera.
    Ogre::Matrix4 worldViewProjection = currStage-&gt;getActiveCamera()-&gt;getCameraViewProjectionMatrix();

    // Transform world coordinates.
    Ogre::Vector3 transformedWorldPosition = worldViewProjection * worldPosition;

    // Calculate screen coordinates from world coordinates.
    Ogre::Vector2 screenPosition;
    screenPosition.x = (int) ( ( ( transformedWorldPosition.x + 1 ) / 2.0 ) * screenRes.width + 0.5 );
    screenPosition.y = (int) ( ( ( 1 - transformedWorldPosition.y ) / 2.0 ) * screenRes.height + 0.5 );

    return screenPosition;
}
</code></pre>

<p>Now I want to convert that screenPosition into Image space to crop an image:</p>

<pre><code>Core::Resolution screenRes = Core::EnvironmentInformation::getSingleton()-&gt;getScreenResolution();
float screenPositionX = (screenPosition.x / screenRes.width) * (pixelBuffer-&gt;getWidth());
float screenPositionY =  (screenPosition.y / screenRes.height) * (pixelBuffer-&gt;getHeight());
</code></pre>

<p><a href="https://i.sstatic.net/p4c3n.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/p4c3n.png" alt="enter image description here"></a></p>

<p>When I click on the mobile screen on the Green LED I get that cropped image.. but what I want is to only crop that green led.. Is there a problem with the transformation ?</p>

<pre><code>  const Core::Resolution cameraRes = Core::EnvironmentInformation::getSingleton()-&gt;getCameraResolutionUpLoad( plane );
    Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture[plane]-&gt;getBuffer( 0, 0 );

    viewarassert( screenPosition.x &lt; cameraRes.width || screenPosition.x &gt;= 0 || screenPosition.y &lt; cameraRes.height || screenPosition.y &gt;= 0 );

   Core::Resolution screenRes = Core::EnvironmentInformation::getSingleton()-&gt;getScreenResolution();
   std::pair&lt; Ogre::Vector2, Ogre::Vector2 &gt; uvBounds = calculateSingleViewTextureCoordinates();

    float screenPositionX = cameraRes.height - (screenPosition.x / screenRes.width) * ((int)pixelBuffer-&gt;getHeight());
    float screenPositionY=  cameraRes.width -  (screenPosition.y / screenRes.height) * ((int)pixelBuffer-&gt;getWidth());

    int  min_x = std::max( 0,(int)screenPositionX - radius);
    int  min_y = std::max( 0,(int)screenPositionY - radius);
    int  max_x = std::min( (int)cameraRes.width, (int) screenPositionX + radius );
    int  max_y = std::min( (int)cameraRes.height, (int) screenPositionY+ radius );

    // Get the pixelbox within the radius.
    pixelBuffer-&gt;lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
    const Ogre::PixelBox &amp;readrefpb = pixelBuffer-&gt;getCurrentLock();

    unsigned char *readrefdata = static_cast&lt;unsigned char*&gt;(readrefpb.data);

    Ogre::Image img;
    img = img.loadDynamicImage (readrefdata, pixelBuffer-&gt;getWidth(),
                                pixelBuffer-&gt;getHeight(), pixelBuffer-&gt;getFormat());
    img = img.flipAroundY();

    Ogre::Image *out = cropImage(img,  min_x, min_y,  max_x,  max_y);
</code></pre>

CC BY-SA 3.0
2017-12-19T04:54:13.143Z
Didn't you ask this on SO as well? https://stackoverflow.com/questions/47857995/transforming-screen-position-into-image-space

Anyways as the guy mentioned I don't understand your transformation matrix. You said perspective projection isn't involved but you name it projection anyways? what is the space of world position after you apply the matrix? Camera space? Projection space?
gallickgunner
<opengl><c++>
I'm trying to get a 2D screen position so I unproject a point from 3D into 2D screen coordinates by that following function:
Andre Ahmed
# I'm trying to get a 2D screen position so I unproject a point from 3D into 2D screen coordinates by that following function:

(Asked by: username_0 on 2017-12-18)

I'm trying to get a 2D screen position so I unproject a point from 3D into 2D screen coordinates by that following function:

```
Ogre::Vector2 SpaceTransformHelper::convertWorldToScreenPosition( const Ogre::Vector3& worldPosition )
{
    Stages::AStage* currStage = Stages::StageManager::getSingleton()->getActiveStage();
    Core::Resolution screenRes = Core::EnvironmentInformation::getSingleton()->getScreenResolution();

    // Get worldviewprojection from camera.
    Ogre::Matrix4 worldViewProjection = currStage->getActiveCamera()->getCameraViewProjectionMatrix();

    // Transform world coordinates.
    Ogre::Vector3 transformedWorldPosition = worldViewProjection * worldPosition;

    // Calculate screen coordinates from world coordinates.
    Ogre::Vector2 screenPosition;
    screenPosition.x = (int) ( ( ( transformedWorldPosition.x + 1 ) / 2.0 ) * screenRes.width + 0.5 );
    screenPosition.y = (int) ( ( ( 1 - transformedWorldPosition.y ) / 2.0 ) * screenRes.height + 0.5 );

    return screenPosition;
}

```

Now I want to convert that screenPosition into Image space to crop an image:

```
Core::Resolution screenRes = Core::EnvironmentInformation::getSingleton()->getScreenResolution();
float screenPositionX = (screenPosition.x / screenRes.width) * (pixelBuffer->getWidth());
float screenPositionY =  (screenPosition.y / screenRes.height) * (pixelBuffer->getHeight());

```

[![enter image description here](https://i.sstatic.net/p4c3n.png)](https://i.sstatic.net/p4c3n.png)

When I click on the mobile screen on the Green LED I get that cropped image.. but what I want is to only crop that green led.. Is there a problem with the transformation ?

```
  const Core::Resolution cameraRes = Core::EnvironmentInformation::getSingleton()->getCameraResolutionUpLoad( plane );
    Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture[plane]->getBuffer( 0, 0 );

    viewarassert( screenPosition.x < cameraRes.width || screenPosition.x >= 0 || screenPosition.y < cameraRes.height || screenPosition.y >= 0 );

   Core::Resolution screenRes = Core::EnvironmentInformation::getSingleton()->getScreenResolution();
   std::pair< Ogre::Vector2, Ogre::Vector2 > uvBounds = calculateSingleViewTextureCoordinates();

    float screenPositionX = cameraRes.height - (screenPosition.x / screenRes.width) * ((int)pixelBuffer->getHeight());
    float screenPositionY=  cameraRes.width -  (screenPosition.y / screenRes.height) * ((int)pixelBuffer->getWidth());

    int  min_x = std::max( 0,(int)screenPositionX - radius);
    int  min_y = std::max( 0,(int)screenPositionY - radius);
    int  max_x = std::min( (int)cameraRes.width, (int) screenPositionX + radius );
    int  max_y = std::min( (int)cameraRes.height, (int) screenPositionY+ radius );

    // Get the pixelbox within the radius.
    pixelBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
    const Ogre::PixelBox &readrefpb = pixelBuffer->getCurrentLock();

    unsigned char *readrefdata = static_cast<unsigned char*>(readrefpb.data);

    Ogre::Image img;
    img = img.loadDynamicImage (readrefdata, pixelBuffer->getWidth(),
                                pixelBuffer->getHeight(), pixelBuffer->getFormat());
    img = img.flipAroundY();

    Ogre::Image *out = cropImage(img,  min_x, min_y,  max_x,  max_y);

```

**Tags:** opengl, c++

> **Comments:**
> **username_1**: Didn't you ask this on SO as well? https://stackoverflow.com/questions/47857995/transforming-screen-position-into-image-space  Anyways as the guy mentioned I don't understand your transformation matrix. You said perspective projection isn't involved but you name it projection anyways? what is the space of world position after you apply the matrix? Camera space? Projection space?  

---

## 2 answers

### Answer by username_2 on 2018-02-17. Score: 1

Not sure if Ogre does it implicitely, but using a 4x4 matrix to transform a 3D point to get the correct 2D coordinates (as it would be rendered with the same matrix), requires a transition from homogeneous coordinates by dividing the result by w.

In other words, you must multiply the matrix by a 4-component vector (x,y,z,1.0f) instead of a 3-component vector. And then the resulting vector will look like (X,Y,Z,W) and you need to divide by W to get the position like it would be rendered.

Like this:

```
// Transform world coordinates.
Ogre::Vector4 transformedWorldPosition = worldViewProjection * Ogre::Vector4(worldPosition,1.0);

//Divide by w 
transformedWorldPosition = transformedWorldPosition / transformedWorldPosition.w; 

// Calculate screen coordinates from world coordinates.
Ogre::Vector2 screenPosition;
screenPosition.x = (int) ( ( ( transformedWorldPosition.x + 1 ) / 2.0 ) * screenRes.width + 0.5 );
screenPosition.y = (int) ( ( ( 1 - transformedWorldPosition.y ) / 2.0 ) * screenRes.height + 0.5 );

```


---

### Answer by username_3 on 2017-12-18. Score: 0

From what I can see, it looks like screenPosition.x is in some sort of screen space and screenPositionX is in terms of the actual pixel buffer in units of pixels. My guess is that cropImage wants its inputs in units of pixels but when you calculate min\_x, min\_y, ... you are using screenPosition.x when you should really be using screenPositionX. Also, where does radius come from? Is it in world space, screen space, or pixel buffer space?

Regardless of whether or not that fixes your problem, try to be more explicit in the future about your variables names to keep track of which space/units you are in. Having a screenPosition.x and a screenPositionX which refer to different things is generally a bad idea.

> **Comments:**
> **username_0**: the radius is pixel buffer space, screenPosition.x is screenspace, and screenPositionX is in actual pixel buffer. I still gets wrong cropped rectangle. Thanks  
> **username_0**: I have edited the post.. still I get wrong cropped image, out of bounds exception  
> **username_3**: Which piece of code gives the out of bounds exception?  
> **username_0**: Ogre::Image *out = cropImage(img,  min_x, min_y,  max_x,  max_y);  
> **username_3**: This is a longshot but maybe you need to clamp the max value to cameraRes - 1 because accessing cameraRes on a zero indexed array would be out of bounds.  

---

