enthought / enthought/mayavi

2D screen point to 3D world point

Open
#1,074 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
1.4k
Forks
316
Avg merge
7h 44m
Merged PRs (30d)
5

Description

I am trying to achieve converting a click on the screen to coordinates in the world on the plane x.y=0 (ie z=0, composed of the x and y axis).

I have found code to convert 3D -> 2D (https://github.com/enthought/mayavi/blob/master/examples/mayavi/advanced_visualization/mlab_3D_to_2D.py), however I am unsure how to go about reversing this as I have not covered those topics at university yet. I have attached a screenshot of my setup so far. It is basically a surface at z=0 on which you will be able to drag a 2D actor. For this, I need to find the point on the surface which was clicked and then handle collision detection using bounds of the 2D actor on the surface.

So far, I am able to get the point clicked in the scene window via:
```
def press_callback(vtk_obj, event):
x, y = vtk_obj.GetEventPosition()
...

self.scene.interactor.add_observer('LeftButtonPressEvent', press_callback)
```

This gives the point from the left-bottom point of the scene UI pane/canvas.

Would it be possible to transform this point to a point on the surface (gray)?

![image](https://user-images.githubusercontent.com/9167240/133099599-58b80db6-fbca-4ed6-b6d0-3b79b5ce5b6d.png)

I have tried using a picker but I can't get the correct bounds to be picked when clicking, when I click on the red shape it is not picked, only when I click within the bounds of the black square I drew on in photoshop does the picker pick the shape. I have checked the `picker.pick_position`, and `picker.actor.bounds`, and they match up. So it seems to me like the `pick_position` is not correctly transformed to the world.

Untitled

However, as you can see by the two white points plotted, the bounds of the red actor/shape are _outside_ the rectangle which is being picked up by the picker. This rectangle of detection bounds scales when you move in and out.

This is how I am calling `picker.pick`:

```
def press_callback(vtk_obj, event):
x, y = vtk_obj.GetEventPosition() # screen point in scene UI pane

result = picker.pick(x, y, 0, self.scene.scene.renderer)
print(picker.pick_position)
if result == 0: # successful pick
return
pickPosition = picker.pick_position
print([o for o in picker.actors])
print("pick", pickPosition, [picker.actor], picker.actor.bounds, picker.actor.position)
if picker.actor == sphere_actor:
print("Bingo")
```

Should I be supplying the `(x, y)` of the click relative to the left-bottom corner of the scene UI?

Any ideas how to progress? I am trying to achieve dragging functionality of the red 2d shape along the surface at z=0. I am just blocked on getting the `Screen Point -> World Point @ surface(z=0)` transformation as I can do the boundary detection myself, no need for the picker. Many thanks!

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.