[vtkusers] Dragging an object in the x-y plane

David Gobbi david.gobbi at gmail.com
Wed Apr 9 17:34:31 EDT 2014


Hi Dov,

I took a quick look at your code, and I notice that on every MouseMove
you compute the dx,dy since the last MouseMove.  I advise that you do
not do this, because it leads to the accumulation of errors.  Instead,
on the ButtonDown, you should save the Display and World coordinates
(i.e. the coordinates at which the drag action started).  Then, in
MouseMove, you should do all your offset calculations relative to this
start position, _not_ relative to the previous MouseMove.  I.e. always
compute dx,dy relative to the position at the start of the drag.

  David

On Wed, Apr 9, 2014 at 2:28 PM, Dov Grobgeld <dov.grobgeld at gmail.com> wrote:
> Thanks David. With your help I almost solved the interaction problem. My
> resulting example creates a board with three pieces on it that may be moved
> around with the right mouse button. The example may be found here:
>
> https://gist.github.com/dov/10310484
>
> It gives a very intuitive feeling for moving the pieces around on the board
> no matter how the board is rotated. But there is still a dragging problem at
> high zoom ins. Then the pieces don't follow the mouse anymore. I'm still at
> lost why his happens.
>
> Feel free to add this example to the vtk example programs.
>
> Regards,
> Dov
>
>
>
> On Wed, Apr 9, 2014 at 12:36 AM, David Gobbi <david.gobbi at gmail.com> wrote:
>>
>> Hi Dov,
>>
>> When you do the Display-to-World, what are you using as the input "Z"
>> display coordinate? Really, I don't think I understand your situation.
>>
>> Generally, if you know that your objects are constrained to move
>> within a certain plane, you should do the following:
>>
>> Let X,Y be the "display" coordinates, in pixel units.
>> Let Z be the display "depth", with a range of [0,1].
>>
>> Convert display coordinate (X, Y, 0.0) to world coordinate (x_near,
>> y_near, z_near)
>> Convert display coordinate (X, Y, 1.0) to world coordinate (x_far, y_far,
>> z_far)
>>
>> Now "far" and "near" define the two ends of a line segment in world
>> coordinates.  These are where the view ray intersects the near and far
>> clipping planes for the vtkCamera.
>>
>> At some point along the segment between "near" and "far", the segment
>> will intersect your constraint plane.  Obviously it does not have to
>> be a plane, it can be whatever kind of constraint surface you want.
>> Let's call this intersection point "surface" because it lies on the
>> constraint surface.
>>
>> So now you have three points in world coordinates: near, surface, and
>> far.  Use Pythagoras to compute:
>>
>> Z = (surface - near)/(far - near)
>>
>> Now Z is the depth at which the view ray at (X,Y) intersects your
>> constraint surface.  Of course, maybe you don't need to compute "Z" at
>> all, maybe you can just leave the surface intersection point in world
>> coordinates.
>>
>> I don't know if VTK has any special functions to do this, but even if
>> it did, I probably wouldn't use them.  I always write my interaction
>> code by thinking about how the view ray intersects my world space, and
>> then by applying a constraint to achieve the desired 2D-to-3D
>> coordinate conversion (or vice-versa).
>>
>>   David
>>
>>
>>
>>
>>
>>
>> On Tue, Apr 8, 2014 at 2:48 PM, Dov Grobgeld <dov.grobgeld at gmail.com>
>> wrote:
>> > Thanks David,
>> >
>> > I got it to work perfectly as long as I'm looking at the scene from the
>> > top.
>> > But when i rotate the scene, e.g. tilt it forward around the x-axis,
>> > then
>> > the dragging of the pieces lags behind the mouse. Geometrically I
>> > somehow
>> > understand why, as I'm constraining to only move the piece in the x-y
>> > plane
>> > and the Display2World transformation is also returning a z-component
>> > that
>> > I'm ignoring. Is there a shortcut in vtk to do the necessary z to x,y
>> > projections, or should i just figure it out on my own? Again, my
>> > requirement
>> > is that the mouse should stay around the same position on the piece, as
>> > I'm
>> > moving it around.
>> >
>> > Regards,
>> > Dov
>> >
>> >
>> >
>> > On Tue, Apr 8, 2014 at 11:19 PM, David Gobbi <david.gobbi at gmail.com>
>> > wrote:
>> >>
>> >> Hi Dov,
>> >>
>> >> I use a function like this:
>> >>
>> >> void DisplayToWorld(vtkRenderer *renderer,
>> >>   double x, double y, double z, // window coordinates (the input)
>> >>   double world[3]) // world coordinates (the output)
>> >> {
>> >>   // Use the vtkViewport interterface for conversions.
>> >>   renderer->SetDisplayPoint(x, y, z);
>> >>   renderer->DisplayToWorld();
>> >>   double hcoord[4];
>> >>   renderer->GetWorldPoint(hcoord);
>> >>   world[0] = hcoord[0]/hcoord[3];
>> >>   world[1] = hcoord[1]/hcoord[3];
>> >>   world[2] = hcoord[2]/hcoord[3];
>> >> }
>> >>
>> >> It is not enough to have just the xy window coordinates.  You also
>> >> need a z window coordinate, which is a depth value in the range [0,1].
>> >> Usually you get the depth from the pick.
>> >>
>> >>   David
>> >>
>> >>
>> >> On Tue, Apr 8, 2014 at 2:03 PM, Dov Grobgeld <dov.grobgeld at gmail.com>
>> >> wrote:
>> >> > I'm trying to create a toy x-y board which has pieces, realized as
>> >> > Actors,
>> >> > that I can drag around in the x-y plane. Through the vtkPicker() I
>> >> > have
>> >> > figured out how to choose a piece, and I can get the render window
>> >> > coordinates through GetInteractor().GetEventPosition(). Further, if I
>> >> > now
>> >> > move the mouse I can calculate a Dx,Dy shift in the window
>> >> > coordinate.
>> >> > But I
>> >> > would now like to translate the Window Dx,Dy to an Actor Dx,Dy shift.
>> >> > I.e. I
>> >> > would like to take a two pairs of xy coordinates in window
>> >> > coordinates
>> >> > and
>> >> > calculate their respective positions in actor coordinates, according
>> >> > to
>> >> > the
>> >> > current actor to dispay matrix. How can I do that?
>> >> >
>> >> > Thanks in advance!
>> >> > Dov
>> >
>> >
>
>


More information about the vtkusers mailing list