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 ;)
Related
I'm extracting door shapes with Cubicasa5k dataset but I don't know how svg draws quarter rounds.
Extracted some nodes of svg files with xml encoding, I found that it had a dictionary including 'd' key and value under of "Panel" id tree node like :
{'d': 'M825.47,986.05 q0.00,-72.92 72.92,-72.92 l0.00,72.92Z'}
It draws like this quarter round on svg image.
I want to draw that shape on raster image with cv2 in Python with that dictionary value.
Read article about 'd' commands but I'm still confused.
How can I draw it?
Okay, I hope I understood that d command of svg clearly now
That arc shape is Bézier curve, and it is drawn concavely based on the outer point, not on the centripetal point.
According to the example above ('M825.47,986.05 q0.00,-72.92 72.92,-72.92 l0.00,72.92Z'), it means drawing process following this:
The starting point of arc shape(called Bézier curve) is (825.47, 986.05).
The drawn reference point exists at a position shifted only to the y-axis. So the reference point is (825.47+0.00, 986.05-72.92) = (825.47, 913.13)
And the end point of arc shape is set following calculation about starting point like 2 : (825.47+72.92, 986.05-72.92) = (898.39, 913.13)
Drawing door shape finishes with drawing straight line that starts from the end point of the curve and ends with l code, it points (898.39+0.00, 913.13+72.92) = (898.39, 986.05)
Simply speaking, the door shape is drawn with arc and straight line, arc starts from left bottom and ends right top, then straight line starts from that right top and ends right bottom.
So if using cv2, should call cv2.ellipse, and set center point from process 4 above, axes(same value will show circle-like shape, so it's radius) from q command above, startangle and endangle(it differs from command above)
I find myself in the situation of having to manually draw a rectangle with rounded edges as a background for a horizontal stack view. To create the classic ios "bubble" effect, such as whatsapp chats, where the text is surrounded by a green shape.
I am attaching the code:
var BackgroundStack = new UIView();
BackgroundStack.Frame = new CGRect(0, -20, TopSchedaStack.Bounds.Width,
TopSchedaStack.Layer.Bounds.Height+40);
BackgroundStack.BackgroundColor = UIColor.TertiarySystemGroupedBackgroundColor;
BackgroundStack.Layer.CornerRadius = 20;
TopSchedaStack.InsertSubview(BackgroundStack, 0);
the perplexity lies in "BackgroundStack.Frame ...", I need to wrap the generated element in the "TopSchedaStack" storyboard of the UIHorizontalStackView type, with a gray rectangle. So I create it with the CGRect function but when I have to position it precisely under the object it is horizontally and vertically constrained to the view and centered. I am struggling, I cannot get the width I expect from the stack. In the storyboard file it is positioned one way but when I go to recover its width with:
TopSchedaStack.Bounds.Width or TopSchedaStack.Frame.Width
The value obtained is not what I expect. I expect the stack to be long from the left edge to the right edge of the view, taking away the guidelines. therefore it is an object constrained to the right and left respectively at point 0.
I would like the gray rectangle to cover the portion of the blue rectangle depicted in the image containing the storyaboard project. I'm pretty much going randomly changing values until it comes back, I'm sure I'll succeed sooner or later but I'm convinced it's not the right way to do this. Can you help me?
I want to combine two SVG paths such that
1.Both paths will be there but, at the area of intersection, there will be no strokes.
2.Second path will be excluded and there will be a complete stroke
See image at http://s18.postimg.org/et4m803rd/shape_combinations.jpg
I want similar function also in HTML5 canvas.
The purpose of this scenario is to implement a lasso selection tool (freehand selection) similar to that of photoshop, with Ctrl and Alt options for adding and subtracting selection [ + some other functions ].
What have you tried? This sounds a little bit like a homework assignment.
The first one is easy to replicate. Just draw the two circles with the stroke, then draw them again in the same place without the stroke.
You can achieve the second shape (the "pacman") by drawing a purple circle on the right that is clipped by a circle that is in the same position as the left (black) circle.
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).
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.