MySQL - Trying to find all points inside a Polygon - mysql

I am trying to query all from a table of points, all of the points that are inside a certain polygon. I have tried to use st_contains() and for some reason it just won't work.
To made it simple, I have made a table with the points (1,1),(0,0),(100,100) I have used:
GeomFromText('Point(0 0)')
This is my query:
SELECT id, astext(point) FROM points WHERE st_within(point,GeomFromText('Polygon(10 10, 10 -10, -10 -10, -10 10, 10 10)'))
I have also found this question, which made me feel confident that there is something very big that I'm missing...
Please, tell me what I'm doing wrong...
Thanks :)

There are two methods to determine if a point is within a polygon (winding number or the even odd rule).
https://www.youtube.com/watch?v=AHs2Ugxo7-8
http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
This depends how you wish to treat a polygon.

Apparently, it is very important that the "Polygon Creation String" will use at least 2 sets of parentheses, even if it's a 1-line polygon. for example:
GOOD Polygon Creation:
GeomFromText('Polygon((10 10,10 -10,-10 -10,10 10))')
BAD Polygon Creation:
GeomFromText('Polygon(10 10,10 -10,-10 -10,10 10)')

Related

checking if point is in polygon giving null values

there are many post relating to this matter but most are old and there seem to be many different way of doing it.
I am trying to see if point exists inside a polygon however it is giving null value even though it is point on polygon.
here is my code.
select ST_contains(ST_geomfromtext('
Polygon((127.090656 37.517137,
127.092416 37.512525,
127.098445 37.513836,
127.095227 37.518346))'), Point(127.090656, 37.517137));
Thanks in advance.
In Mysql you need to close the polygon therefore I must add first point at the end of polygon again.
select ST_contains(ST_geomfromtext('
Polygon((**127.090656 37.517137**,
127.092416 37.512525,
127.098445 37.513836,
127.095227 37.518346,
**127.090656 37.517137**))'), Point(127.090656, 37.517137));
which now fixes my problem
and for cleaniness
I can set polygon as
SET #location_1 = ST_geomfromtext('
Polygon((**127.090656 37.517137**,
127.092416 37.512525,
127.098445 37.513836,
127.095227 37.518346,
**127.090656 37.517137**))');
select ST_contains( #location_1, Point(127.090656, 37.517137));
which to me is much cleaner. But maybe it require more memory for #location_1 in db (I'm not sure)?

MySQL ST_CONTAINS on Overlap case

I'm facing a problem using the ST_CONTAINS geospatial function on MySQL 5.6.31.
I've the following MULTIPOLYGON:
I need to check if some point is inside a MULTIPOLYGON, in this case the red one on the image, so i do:
SET #g1 = ST_GEOMFROMTEXT('MULTIPOLYGON(((41.94142040508967 12.41757292797851,41.94442097040815 12.419032049682611,41.93529115206086 12.43456740429687,41.91939065648979 12.425126028564447,41.92475512204906 12.407702398803705,41.94142040508967 12.41757292797851),(41.92552143745503 12.409933996704096,41.90987400689221 12.402638388183588,41.90252797153794 12.421864462402338,41.907446714803015 12.433194113281244,41.92603230927889 12.419461203124994,41.92552143745503 12.409933996704096,41.92552143745503 12.409933996704096),(41.906248516384416 12.397567221513638,41.89551602293968 12.423402258745083,41.90101026279693 12.430268713823208,41.90771770545893 12.420398184648404,41.91033661082307 12.39653725325192,41.906248516384416 12.397567221513599,41.906248516384416 12.397567221513599,41.906248516384416 12.397567221513638,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.397567221513638)))');
SET #g2 = POINT(41.9059998,12.4159939);
SELECT ST_CONTAINS(#g1,#g2);
The result is 0.
If i change the point, specifying for example a point in the upper polygon, i got 1.
Why this behaviour? It seems that when two polygons overlaps the ST_CONTAINS see it as en empty part of them.
What can i do?
Thanks to all!
That's a weird (not standard compliant and probably invalid) multipolygon.
Multipolygon is described as something like:
MULTIPOLYGON(((p1_shell), (p1_hole1), (p1_hole2)), ((p2_shell), (p2_hole1), (p2_hole2)))
I.e. polygons are separated by double round brackets, and polygon shell is separated from holes by single round brackets. In your case it is single brackets - so this WKT describes a single polygon with two holes! Note that it is not a valid one (you can call ST_IsValid to check) - the hole is not fully contained within the shell as required by standard But anyway MySql allows this, and since the red point is within hole, it is not contained by the shape, so MySql result is correct.
If the desired semantic of the shape is a multipolygon, not polygon with holes, replace ),( with )),(( to get that semantics. Note that this is still not valid WKT shape - individual polygons in a multipolygon are not allowed to intersect (again check with ST_IsValid). But it should give you correct result anyway (although, being non-standard, this is somewhat undefined behavior).
If you want to be standard-compliant, you should clean this WKT. What you do depends on semantics you need. Maybe ST_UNION these polygons and get a single one. Or to keep all three - the correct way to describe a shape consisting of possibly intersecting polygons is GEOMETRYCOLLECTION with polygons as members.

Store circle in MySQL GeoSpatial Database

I want to be able to store a circle using a fixed point g and radius d, then get those values back when retrieving the information.
The only way I've found to use those arguments to create a geographic object is to use buffer which produces a polygon:
https://dev.mysql.com/doc/refman/5.6/en/spatial-operator-functions.html#function_buffer
SELECT ASTEXT( BUFFER ( POINT( 10, 10 ), 5 ) );
| POLYGON((10 0,9.50932325672582 0.012045437948275506,9.019828596704395 0.048152733278032045,8.532695255446383 0.10823490035219052,8.049096779838717 0.1921471959676957,7.570198200967361 0.2996874680545609,7.097153227455378 0.4305966426779104,6.631101466077799 0.5845593481697922,6.173165676349102 0.7612046748871322,5.724449065697179 0.9601070687655664,5.286032631740024 1.1807873565164506,4.858972558067784 1.4227138999972784,4.444297669803978 1.6853038769745474,4.043006955075667 1.9679246851935517,3.6560671583635447 2.2698954663726303,3.2844104515298165 2.5904887464504087,2.9289321881345254 2.9289321881345254,2.5904887464504087 3.2844104515298165,2.2698954663726303 3.6560671583635447,1.9679246851935517 4.043006955075667,1.6853038769745474 4.444297669803978,1.4227138999972784 4.858972558067784,1.1807873565164506 5.286032631740024,0.9601070687655664 5.724449065697179,0.7612046748871322 6.173165676349102,0.5845593481697922 6.631101466077799,0.4305966426779104 7.097153227455378,0.2996874680545609 7.570198200967361,0.1921471959676957 8.049096779838717,0.10823490035219052 8.532695255446383,0.048152733278032045 9.019828596704395,0.012045437948275506 9.50932325672582,0 10,0.048152733278032045 10.980171403295605,0.10823490035219052 11.467304744553617,0.1921471959676957 11.950903220161283,0.2996874680545609 12.429801799032639,0.4305966426779104 12.902846772544622,0.5845593481697922 13.368898533922202,0.7612046748871322 13.826834323650898,0.9601070687655664 14.27555093430282,1.1807873565164506 14.713967368259976,1.4227138999972784 15.141027441932216,1.6853038769745474 15.555702330196022,1.9679246851935517 15.956993044924333,2.2698954663726303 16.343932841636455,2.5904887464504087 16.715589548470184,2.9289321881345254 17.071067811865476,3.2844104515298165 17.409511253549592,3.6560671583635447 17.73010453362737,4.043006955075667 18.03207531480645,4.444297669803978 18.314696123025453,4.858972558067784 18.577286100002723,5.286032631740024 18.81921264348355,5.724449065697179 19.039892931234434,6.173165676349102 19.238795325112868,6.631101466077799 19.41544065183021,7.097153227455378 19.569403357322088,7.570198200967361 19.70031253194544,8.049096779838717 19.807852804032304,8.532695255446383 19.89176509964781,9.019828596704395 19.95184726672197,9.50932325672582 19.987954562051726,10 20,10.49067674327418 19.987954562051726,10.980171403295605 19.95184726672197,11.467304744553617 19.89176509964781,11.950903220161283 19.807852804032304,12.429801799032639 19.70031253194544,12.902846772544622 19.569403357322088,13.368898533922202 19.41544065183021,13.826834323650898 19.238795325112868,14.27555093430282 19.039892931234434,14.713967368259976 18.81921264348355,15.141027441932216 18.577286100002723,15.555702330196022 18.314696123025453,15.956993044924333 18.03207531480645,16.343932841636455 17.73010453362737,16.715589548470184 17.409511253549592,17.071067811865476 17.071067811865476,17.409511253549592 16.715589548470184,17.73010453362737 16.343932841636455,18.03207531480645 15.956993044924333,18.314696123025453 15.555702330196022,18.577286100002723 15.141027441932216,18.81921264348355 14.713967368259976,19.039892931234434 14.27555093430282,19.238795325112868 13.826834323650898,19.41544065183021 13.368898533922202,19.569403357322088 12.902846772544622,19.70031253194544 12.429801799032639,19.807852804032304 11.950903220161283,19.89176509964781 11.467304744553617,19.95184726672197 10.980171403295605,19.987954562051726 10.49067674327418,20 10,19.95184726672197 9.019828596704395,19.89176509964781 8.532695255446383,19.807852804032304 8.049096779838717,19.70031253194544 7.570198200967361,19.569403357322088 7.097153227455378,19.41544065183021 6.631101466077799,19.238795325112868 6.173165676349102,19.039892931234434 5.724449065697179,18.81921264348355 5.286032631740024,18.577286100002723 4.858972558067784,18.314696123025453 4.444297669803978,18.03207531480645 4.043006955075667,17.73010453362737 3.6560671583635447,17.409511253549592 3.2844104515298165,17.071067811865476 2.9289321881345254,16.715589548470184 2.5904887464504087,16.343932841636455 2.2698954663726303,15.956993044924333 1.9679246851935517,15.555702330196022 1.6853038769745474,15.141027441932216 1.4227138999972784,14.713967368259976 1.1807873565164506,14.27555093430282 0.9601070687655664,13.826834323650898 0.7612046748871322,13.368898533922202 0.5845593481697922,12.902846772544622 0.4305966426779104,12.429801799032639 0.2996874680545609,11.950903220161283 0.1921471959676957,11.467304744553617 0.10823490035219052,10.980171403295605 0.048152733278032045,10.49067674327418 0.012045437948275506,10 0)) |
1 row in set (0.00 sec)
My problem with this is that I cannot retrieve the point and radius when selecting this row in the future, instead I get the polygon back.
Is there not a better way to store a circle for use with MySQL GeoSpatial Extensions?
Spatial databases are not great at storing curves; rather they tend to be approximated by lots of straight segments, so you're not actually retaining a circle. Support for curved geometries is improving but it's still not really there.
I would probably store the geometry as you have, as well as the radius as a floating point value.
Alternatively, if you only want to store the geometry, you can obtain the centre of the polygon ("circle") with the Centroid function, and then get the radius by converting the polygon to a line and determining the distance between the centroid and the line. There are other ways to determine this distance, too. the caveat is that because this is only an approximation of a circle, the distance between the centre of the circle and its edge is different when measured between the centre and one of the vertices, and when measured from the centre and an edge between two vertices. So if you do not store the radius independently of the geometry, ideally you should measure distance between a vertex and the centre, which will be equal to the original radius (buffer distance). Practically the difference will be rather small so long as your "circle" has dense vertices.

Inverted Smoothstep?

I am currently trying to simulate ballistics on an object, that is otherwise not affected by physics. To be precise, I have a rocket-like projectile, that is following an parabolic arc from origin to target with a Lerp. To make it more realistic, I want it not to move at constant speed, but to slow down towards the climax and speed up on its way back down.
I have used the Mathf.Smoothstep function to do the exact opposite of what i need on other objects, i.e. easing in and out of the motion.
So my question is: How do I get an inverted Smoothstep?
I found out that what i would need is actually the inverted formula to smoothstep [ x * x*(3 - 2*x) ], but being not exactly a math genius, I have no idea how to do that. All I got from online calculators was some pretty massive new function, which I'm afraid would not be very efficient.
So maybe there is a function that comes close to an inverted smoothstep, but isn't as complex to compute.
Any help on this would be much appreciated
Thanks in advance,
Tux
Correct formula is available here:
https://www.shadertoy.com/view/MsSBRh
Solution by Inigo Quilez and TinyTexel
Flt SmoothCubeInv(Flt y)
{
if(y<=0)return 0;
if(y>=1)return 1;
return 0.5f-Sin(asinf(1-2*y)/3);
}
I had a similar problem. For me, mirroring the curve in y = x worked:
So an implementation example would be:
float Smooth(float x) {
return x + (x - (x * x * (3.0f - 2.0f * x)));
}
This function has no clamping, so that may have to be added if x can go outside the 0 to 1 interval.
Wolfram Alpha example
If you're moving transforms, it is often a good idea to user iTween or similar animation libraries instead of controlling animation yourself. They have a an easy API and you can set up easing mode too.
But if you need this as a math function, you can use something like this:
y = 0.5 + (x > 0.5 ? 1 : -1) * Mathf.Pow(Mathf.Abs(2x - 1),p)/2
Where p is the measure of steepness that you want. Here's how it looks:
You seem to want a regular parabola. See the graph of this function:
http://www.wolframalpha.com/input/?i=-%28x%2A2-1%29%5E2%2B1
Which is the graph that seems to do what you want: -(x*2-1)^2+1
It goes from y=0 to y=1 and then back again between x=0 and x=1, staying a bit at the top around x=0.5 . It's what you want, if I understood it correctly.
Other ways to write this function, according to wolfram alpha, would be -(4*(x-1)*x) and (4-4*x)*x
Hope it helps.

game - how can I drag objects (cars with numbers) into targets (start line) AS3.0.?

I am having this problem, where I have several cars, numbers and letters, and need to put 5 cars in the starting places. -random order is ok.
I' having trouble finding in AS3 a way so that the EndX and EndY of each object can be in the starting lines and be considered right no matter the order!
I'm having trouble putting the code here so, heres a titanpad with the code:
this is the code:
being (um, dois, tres, quatro) the movieclip instance name for each numbered car.
https://titanpad.com/42vtnCbvLu
First of all, you could probably benefit by using the distance between two points formula and seeing if the distance is less than a certain value rather than checking in all 4 directions manually:
Math.abs(Math.sqrt((x2-x1)^2 + (y2-y1)^2))
Let the position of the car be (x1,y1) and the start position (x2,y2).
This formula will give you the distance between the two points in any direction, and you could test maybe whether this value is less than your offset.
As for the cars in any order part, I'm interpreting that you have your cars and you want the user to drag them to one of 5 spots, a bit like this:
spot1
spot2
spot3
spot4
spot5
All with respective coordinates. My suggestion would be to have a boolean flag for whether each spot is occupied that stops the program checking whether a car is put there after it has been taken once.
Once all these flags are true, then you can proceed.
Hope this helps.