Here's how to turn a mouse click into a field easting and northing position

This is not a feature request nor a bug. Just informational, perhaps future versions of AOG will want to take advantage of this. I spent a long time searching google until I stumbled on this, so I’m posting it here so I can find it again some day.

Here are the steps for taking a mouse click viewport coordinate (0,0 is bottom left in GL world, so opposite of the screen) and translating them into field easting and northing coordinates. The code posted here is C++ with Qt, but C# has the exact same functionality in its matrix library.

QMatrix4x4 modelview;
QMatrix4x4 projection;

//convert screen coords to GL viewport coords:
float y = viewport_height - mouse_y
float x = mouse_x

//this must be exactly the same as what OpenGL.Designer.cs does when setting up openGL for drawing:
//  Create a perspective transformation.
projection.perspective(glm::toDegrees(fovy), width / (double)height, 1.0f, camDistanceFactor * camera.camSetDistance);


//camera does translations and rotations, from CCamera
//back the camera up
modelview.translate(0,0,camSetDistance * 0.5);

//rotate the camera down to look at fix
modelview.rotate(camera.camPitch, 1.0, 0, 0);

//pan if set
modelview.translate(panX, panY, 0);

//following game style or N fixed cam
if(camera.camFollowing) {
    modelview.rotate(camera.camYaw, 0,0,1);
    modelview.translate(camera.-camPosX, camera.-camPosY, camera.-camPosZ);
} else {
    modelview.translate(camera.-camPosX, camera.-camPosY, camera.-camPosZ);

/* only do this if you want to pan the field with the mouse
modelview.translate(vehicle.pivotAxlePos.easting, vehicle.pivotAxlePos.northing, 0);
modelview.translate(sin(vehicle.fixHeading) * tool.hitchLength,
                            cos(vehicle.fixHeading) * tool.hitchLength, 0);
//rotate to face vehicle heading
modelview.rotate(glm::toDegrees(-fixHeading), 0.0, 0.0, 1.0);
if (camera.camFollowing)
    modelview.rotate(glm::toDegrees(-fixHeading), 0.0, 0.0, 1.0);

//get point on the near plane
QVector3D worldpoint_near = QVector3D( { x, y, 0} ).unproject(modelview,projection,QRect(0,0,viewport_width, viewport_height));
//get point on the far plane
QVector3D worldpoint_far = QVector3D( { x, y, 1} ).unproject(modelview, projection,QRect(0,0,viewport_width, viewport_height));
//get direction vector from near to far
QVector3D direction = worldpoint_far - worldpoint_near;

//determine intercept with z=0 plane, and calculate easting and northing
double lambda = -(worldpoint_near.z()) / direction.z();
mouseEasting = worldpoint_near.x() + lambda * direction.x();
mouseNorthing = worldpoint_near.y() + lambda * direction.y();

I don’t pretend to understand how it works but it does work.

Note. I think it finally is working right. Regardless of field’s orientation on the screen it gets the right easting and northing coordinate.

For click to drag panning, though, the modelview has to be rotated and translated. Then the results can be added to panX and panY. then click and drag the field around.

I’ll take a look at it. Biggest trouble is the areas on the screen that we use to click for other functions. Brian just added a pan zoom set of buttons to the main screen.

Click coordinates would be great for other functions as well.


Yes I saw that. Nice addition.

Probably the best way to utilize clicking directly on the field is to only use clicks that aren’t used anywhere else. In other words, once a mouse click has been determined to be none of those onscreen features, then it could be treated as a field coordinate.

Just FYI, all the matrix code must match the GL matrix manipulations done in ogl_Paint() exactly.

While testing this calculation out, I found that if you put in the final rotation stuff that is commented out in the above example, you can get easting and northing offsets relative to the tractor itself, which turned out to be perfect for creating drag to pan. So in my resurrected QtAOG port I currently have click and drag the field which works via the existing AOG panning mechanism. I was surprised how well it works. But I’m not sure if this is a feature I want to keep or not… if I click on something in the field and hold just a little too long it will move the field, which may not be so great in a bouncing cab. Although on a tablet with multi-touch, the drag to pan function could be done with two fingers (also pinch to zoom). But as far as AOG goes, I don’t think winforms supports multitouch at all.

Yes, winforms will not allow for that. I added a similar routine to the abdraw form. I actually used it create screen measure tools.

1 Like

I would have it activated by a button or something… Either on the main screen or in the features page… Give me the word and I’ll add it :grin: