How is polygon described?

Drag and Drop glued to polygon sides

  • Looking for tips on implementing drag and drop that snaps to the nearest point on a polygon. I've written an application that places markers (the markers are circles where the center point of each is on a polygon side) along the outer sides of any polygon according to a specific formula. The formula is exact enough that the majority of markers is placed correctly, but I'll need the ability to drag and drop markers to make fine-tuned adjustments in some cases. The markers are already draggable, but they're free-form draggable, meaning that I have to be very careful and exact about where I drag them, if I want a dragged marker to be aligned exactly like the automatically-placed markers. Requirements: 1. A marker that has been dragged should, when it's dropped, be affixed to a polygon side - specifically, to the point on the side that is closest to the mouse position when dropping. 2. It would be nice, but not necessary to have the markers affixed to a side of the polygon while they're being dragged. I'm afraid this may introduce too much complication and slow things down, though. 3. It must be possible to drag a marker from its starting side to all other sides. 4. The algorithm must be efficient - I don't want to add so much computation that dragging is no longer fluid. This application is used primarily on Android tablets, so performance is more of a factor than for a PC-based application. 5. It would be nice to have a 'snap' capability that moves the marker in increments of X pixels along the walls, but this is something I could add later. I've thought a good deal about this. I've considered using vector math to measure the distance of the mouse to each side of the polygon while dragging, and choosing the side with the shortest distance / the point on that side. I'm worried that this much computation will slow the app down for complex polygons. I've also considered setting a center point on the polygon, drawing a ray from that point to the mouse location and using the intersection of that ray with a polygon side to determine the marker's location while dragging. With the snap idea in mind, I've thought about generating a list of points on all sides that could be snapped to, and choosing the one that's closest to the mouse position. Hoping someone's worked with something similar and might have some helpful tips.

  • Answer:

syzygy at Ask.Metafilter.Com Visit the source

Was this solution helpful to you?

Other answers

Try the accurate method first (finding the closest point on the closest edge). Then make the obvious optimizations -- e.g. ignore edges that can't possibly be close enough. I bet this will be fast enough; it's really not that much math. No reason to reach for approximations until you've found that the accurate way is too slow in your particular situation.

xil

So, to find the side of the polygon closest to a point, you need only look at the vertices. The closest edge will have one of it's vertices as the closest point to your mouse cursor, erm, provided we're talking about convex polygons (are we?) From there you can decide which side is closest by picking the one that has the other vertex closest, I think. I'd have to get out a piece of paper to be sure. Once you know the closest line segment, you easily find the closest point on that line. Imagine a triangle formed by the vertices of that line and your mouse cursor. Call the mouse cursor M and the point you're looking for P. (M-P) will be a vector that is a right angle to your line segment. This is going to be hard for me to describe with out a picture... Pick one vertex of your poly segment, call that angle A. The distance from that vertex to your mouse, let's call M. Since we have a right triangle now, the length along the segment from your chosen vertex (let's say L) is defined by cos(A) = L/M. We're looking for L, so L = cos(A)*M. And there's you're closest point.

RustyBrooks

I don't know what programming language you're using (java I guess?) but if you're stuck I could probably code up a simple demo for you in something.

RustyBrooks

Are you talking about, like, Javascript?

rhizome

I just wrote something very similar yesterday, but I'm on my phone at the moment, so I can't type out the equations. It's actually fairly simple. I'll write it out when I get home in a few hours.

WasabiFlux

These polygons can be convex or concave (or a mix of the two). At the moment, I'm working on a solution that only calculates the point when I drop the marker. The first iteration will find the closest point on each side of the polygon to the provided point, and will return the one with the shortest distance to the provided point. Javascript is the language, and I've written a small geometry library that has a number of line, point and polygon utilities.

syzygy

OK I put something together, it works with any kind of polygon. I wrote it in tcl but hopefully you can figure out the basic algorithm? If you have tcl/tk installed you can run with like wish ./test.tcl on your machine. Move the mouse in the window and a purple dot will show the closest snapped point. Granted I am running this on a regular PC but it's in the 300 microsecond range for me.

RustyBrooks

I even just tried it with a polygon that crosses itself and it still works fine, btw.

RustyBrooks

It's been some time since I used it (and the documentation always seems to be going backwards for me), but could you use jQuery's http://jqueryui.com/demos/droppable/ as the basis and then just tweak the tolerances and drop target logic? Just thinking that might be easier than maintaining an entire geometry library.

yerfatma

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.