Math for zoom to cursor on mouse wheel scrolling - graphics

Have to implement a Directx9 project that involves zoom towards the cursor like Google maps with the mouse scroll wheel
(similar to this implementation by Phrogz).
Need the math and the variables required for the same.

Solved this problem using below steps
Decide per scroll movement, call it Z-SHIFT, in Z-direction towards the target point
such that the camera should travel to target in fixed scrolls(SCROLL_COUNT)
Calculate the distance to travel in X and Y directions, say DIST_X and DIST_Y
Movement per scroll in X-direction and Y-direction will be calculated as
X-SHIFT = DIST_X/SCROLL_COUNT
Y-SHIFT = DIST_Y/SCROLL_COUNT
Z-SHIFT = Pre decided suitable value
We have mathematical equation to guide the coordinates of the camera per scroll which when placed in the code provides the required zoom to cursor effect.

Related

How to get edges of a polygon using pixijs?

I'm using pixi.js to create some editable polygons. So, what I want to achieve is this:
I have one polygon
Then, when I hit the edge a small circle should appear
And next I can drag and drop that part of the edge to creating a new point for the polygon
For now, what I know is the polygon vertices and I'm thinking to use the line function (y=mx+b) to check if the point where the mouse is belongs to the edge. My problem here, is that I have no idea how to obtain that edges. Any Suggestion? Of course, if you have any other idea to do this feel free to share =).
For now, what I know is the polygon vertices
You probably draw your polygon using https://pixijs.download/dev/docs/PIXI.Graphics.html#drawPolygon method by passing to it a list of points - similar as last shape in this example: https://pixijs.io/examples/#/graphics/simple.js
// draw polygon
const path = [600, 370, 700, 460, 780, 420, 730, 570, 590, 520];
graphics.lineStyle(0);
graphics.beginFill(0x3500FA, 1);
graphics.drawPolygon(path);
graphics.endFill();
^ In that example we have 5 points: P (600, 370), Q (700, 460), R (780, 420), S (730, 570), T (590, 520).
It also means that we have 5 edges: PQ, QR, RS, ST, TP
Now, we should have some way to tell if mouse pointer "is hovered over some some edge". By "is hovered" i mean: it lies in some distance from edge - lets say said distance is 10 pixels. So we want to know if mouse pointer is 10 pixels away from some edge.
To know that we can use formula explained in Line defined by two points part in: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points
P1=(x1,y1) and P2=(x2,y2) - are the beginning and end vertices of some edge (for example PQ)
(x0,y0) is our "mouse point"
You can iterate over all edges and perform above calculation - if the distance is less that 10 pixel for some edge then you have the answer. If there is more than one edge which meets this requirement then you should pick one with smallest distance (it can happen if for example mouse is placed near some vertice).
Now you have the selected edge. Now lets do following point from your question:
2. Then, when I hit the edge a small circle should appear
To calculate position of this circle we can use equation from same Wikipedia page: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_an_equation - the part The point on this line which is closest to (x0,y0) has coordinates:.
Here you need to convert coordinates of vertices from your selected edge to line function.
Then we can proceed to last point from your question:
3. And next I can drag and drop that part of the edge to creating a new point for the polygon
You can do it by adding new vertice to your polygon.
Lets assume that selected edge is PQ - then this new vertice should be added between vertices P and Q in the vertices list which you pass to drawPolygon method. Lets name this new vertice X. Coordinates of vertice X should be equal to current mouse coordinates.
Then you will have following edges: PX, XQ, QR, RS, ST, TP.
You probably want to activate this "mode" after mouse is clicked and when mouse button is down etc - but that is separate issue related to interactivity / GUI etc - not graphics :) .
Note: is good to separate your presentation part of application (graphics / pixi.js related things) from mechanics and interactivity / GUI etc. So for example: do your calculations in separate place (other class, method etc) from where you do your actual drawing (calling pixi.js methods, update canvas etc). Store results of calculations in some place (from above example it would be: list of vertices, position of circle, colors etc), and then when time comes to draw you take those results and just draw polygons using them. Dont mix everything in one place ;)

Re-scaling x, y-axis on capture correct coordinate scale on mouse-over in matplotlib

I am rendering a data as shown below using cluster analysis.
As you can see that ports in the range of 0-200 are clubbed together. Is there a way to zoom in on the scale when I mouse over a coordinate and thereby redrawing that section of the graph again in a zoomed window. What i mean is that for the coordinates shown in blue circle, when I mouse over, I want the x, y axis redrawn for 0-10000 using a different scale so that overlapping circles move apart. Is it possible ?. I must confess I find matplotlib little challenging and my apologies if my question is little cryptic. thanks for the help!
Assuming youre using pyplot then this functionality is built right in to the pyplot output.
See the following from the matplotlib documentation.
The Zoom-to-rectangle button
Click this toolbar button to activate this mode. Put your mouse somewhere over an axes and press the left mouse button. Drag the mouse while holding the button to a new location and release. The axes view limits will be zoomed to the rectangle you have defined. There is also an experimental ‘zoom out to rectangle’ in this mode with the right button, which will place your entire axes in the region defined by the zoom out rectangle.
If you need to enable zoom to rectangle functionality without actually clicking then this will be possible by creating a transparent figure positioned in a location of your choice on your plot and then initiating a matplotlib event to be handled when the mouse hovers over this area. This functionality is not built in and will require customisation.
Detail relating to event handling on mouseover events can be found at this URL

Calculate distortion in equirectangular projection on a sphere

Following Quote from this source:
http://www.cambridgeincolour.com/tutorials/image-projections.htm
Equirectangular image projections map the latitude and longitude
coordinates of a spherical globe directly onto horizontal and vertical
coordinates of a grid, where this grid is roughly twice as wide as it
is tall.
I have a 13312 px width and 6656 pixel height Panorama picture. It's a equirectangular projection of a room and have a 2:1 ratio.
I use following formular to calculate the xPosition:
var xPosition = ( panorama.width / 360 ) * azimuth
Azimuth = Phi = Heading = Angle to the left or right
How do I project this now on a 1366x768px browser screen?
I think my results are wrong, because it's not on the point where it should be.. it could be because the sphere has a distortion on the left and right:
Is there any formular to calculate the position with attention to the distortion and scale it to fit on the browser screen? I looked many (MANY) sources to find a solution for this, but they always just say that equirectangular are just lat and long.. they don't consider the distortion.
Last question: To find a special solution, I tryed to put a plane on the circle and expanded the line which shows the alpha angle. I though with Phytagoras I could find the position.. but this didn't worked either.. maybe I did something wrong? Is this the way even possible or am I doing it wrong?
edit
THIS is what I'm actually looking for: http://othree.github.io/360-panorama/three-2d/
The black grid in the background. What is the name of this? For what do I have to google or look for? When you start the 2D Panorama, if you want to get the coordinations of the top right corner of the window, what do you have to do?
The whole calculation problem was about to create a Google Streetview similiar view from a 2:1 equirectangular image. We already found a solution for this with a great help from Martin Matysiak (https://github.com/marmat | Google).
It's been a while so I can't give a direct answer to what the main solution is, but I can provide a URL to an AddOn Martin wrote for adding the custom Markers that we actually were trying to make.
You can follow https://github.com/marmat/google-maps-api-addons and look for yourself. In the end it helped a lot to solve the main problem and let us continue with our main Framework for Google Business Tours.
If you follow the link in the threejs demo you included, it would take you to the source code.
particularly look at:
https://github.com/mrdoob/three.js/blob/dev/examples/webgl_panorama_equirectangular.html
and
https://github.com/mrdoob/three.js/blob/dev/src/geometries/SphereBufferGeometry.js
not sure if there is distortion though. The distortion comes from the fact that the texture is mapped to the sphere, and the sphere is rendered in 3D (openGL).

How to drag a polygon in MFC?

I'm new to MFC. I know how to draw a line and how to scribble in MFC. I use CDC and some functions such as LineTo() and MoveTo() to do this. Moreover, I've got FillRect() and Rectangle().Now I want to drag my rectangle or any polygon in the view.It's like you drag a icon on your desktop.
I think the first step is to get the region.Then erase the old polygon and when the mouse move draw a same polygon which depends on the point where the mouse go.
So I search region in MSDN and I got Region class and CRgn class.But before I look into these two class I want to know whether I'm in the right direction.
I need more suggestions on how to learn MFC. Actually,all I need is to finish my homework which is mainly about draw polygons and drag them and link them by line. And I hope I can finish this homework all by myself and MSDN. Can MSDN help me do that?
The CDC::Polyline function will draw a polygon much faster than using LineTo and MoveTo.
You do not need region and do not need to erase the old polygon. Instead, you need to draw everything in the view OnDraw. Any change you want to make with the mouse should change the array of coordinates that represent the polygon and then call Invalidate. In other words, do not draw in the mouse message handlers. Calling Invalidate in the mouse message handlers will cause OnDraw to be called later and it should repaint the entire view.

Graphics Question: How do I restrict the mouse cursor to within a circle?

I'm playing with XNA. When I click the left mouse button, I record the X,Y co-ordinates. Keeping the mouse button held down, moving the mouse draws a line from this origin to the current mouse position. I've offset this into the middle of the window.
Now, what I'd like to do is restrict the mouse cursor to within a circle (with a radius of N, centred on the middle of the screen). Restricting the mouse to a rectangular region is easy enough (by adjusting the origin by the difference of the mouse position and the size of the region), but I haven't a clue on how to start doing it for a circular region.
Can anyone explain how to do this? Any advice on where to start would be helpful.
I don't have a clue about how to use XNA... so can't give you specific code, but the idea is simple.
Just check the distance between current mouse position and the origin with Pythagora's theorem:
dist = sqrt((current_y - orig_y)^2 + (current_x - orig_x)^2)
Then check that dist is < radius
You need, every time the mouse moves, to restrict it to a rectangle between its current position and the nearest point on the circle.
The nearest point on the circle is got by
let (x,y) be where the mouse is, (x0,y0) be the origin
(x0-x, y0-y) is the vector from origin to pointer
d=sqrt((x0-x)2+(y0-y)2) is the length of that vector
(N*(x0-x)/d, N*(y0-y)/d) is then the point at distance N from the origin along the line joining the origin to the mouse position - that is, the nearest point on the circle to the mouse pointer.

Resources