Using JTS, how to find the nearest point on a polygon's boundary from an outside point? - topology

Using JTS, how to find the nearest point on a polygon's boundary from an outside point?

Check out the DistanceOp. It returns an array of Coordinates:
Coordinate[] pts = DistanceOp.closestPoints(poly, outsidePoint);
pts[0] will be the point on the first geometry (in this case the polygon) and pts[1] will be on the second geometry (so, the same outside point you just passed in).

Related

Inserting tags by clicking on the objet

I have a question about the coordinates of the model.
Would it be possible to register a problem with a tag in the model, defining the exact location by clicking on the model?
enter image description here
PS.: on this example, only it is possible to use central coordinates of the object
To get the exact x,y,z value, use this 'ALT-key pivot point' technique, to get the surface point of a model, instead of it's centroid:
https://github.com/wallabyway/markupExt/issues/2
Second part:
Once you have the x,y,z value, you can replace 'centroid' position calulation, in this post:
https://forge.autodesk.com/blog/placing-custom-markup-dbid
// get the center of the dbId (based on its fragIds bounding boxes)
const pos = this.viewer.worldToClient(this.getModifiedWorldBoundingBox(id).center());
Does that help?

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.

Formula to convert Local coordinates to world coordinates

Can someone give me the formula?
I have a vector3d which represents the position of a vertex in local coordinates, I have a Matrix3d that represents the rotation and position of the object which this vertex is part of it's geometry, how do I convert the local position of this vertex to the coordinates of the world?
now it's working, I had a problem with keeping the original vertex3d, and I played with the order and this is working, thank you very much, here is the code, I did have to use m2.invert(); here is the code:
var m3d:Matrix3D = new Matrix3D();
obj.Transform.copyToMatrix3D(m3d);
var m2:Matrix3D = new Matrix3D();
m2.append(m3d);
m2.invert();
m2.prependTranslation(obj.BoundingBox[i].x,obj.BoundingBox[i].y,obj.BoundingBox[i].z);
obj.BoundingBox[i] = new Vector3D(m2.position.x,m2.position.y,m2.position.z);
in fact as I did it in the first place was also OK:
var m3d:Matrix3D = new Matrix3D();
obj.Transform.copyToMatrix3D(m3d);
m3d.invert();
obj.BoundingBox[i] = m3d.transformVector(obj.BoundingBox[i]);
The only thing I was missing was the invert(); and I wish I knew what it is for...
Some people told me I have to append (or prepend) the object matrix and then the world matrix, which makes sense, but adding the world matrix only caused me problems, while the invert(); made it good, but why?
Vesper, you are the one suggested it, thanks but why?
I know why, someone experienced gave me the answer: the camera shows everything mirrored, when you go left the world seems to be moving right, so you need to invert.

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.

AS3 Polar coordinate from Cartesian coordinate

I'm playing with body animation in AS3. I did a body with all parts (excluding fingers) and make a XML with the "skeleton". The XML got the instances of each part and the place of the articulation of the next part. I make it work with cardinal coordinates (x,y) and the body moves when I rotate a part and recalculate all the links again (each part in each articulation).
However, this will demand some calculation each little modification of the body, so now I'm optimizing it. As for de design x,y is easier, so when the body instance is created, the class re-build the XML converting coordinates to Polar system (r,t), like this ("Quadro" is the node with coordinates):
dx = Quadro.#x;
dy = Quadro.#y;
Quadro.#r = Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2));
Quadro.#t = (dy>0)? Math.asin(dx/Quadro.#r) : Math.acos(dy/Quadro.#r);
I did some changes to make it work but at list one quadrant is always wrong! In this case, the upper left is wrong. The neck and the head should be in this place and they are in upper right (mirrored).
Any tips for a right conversion in AS3?
Try to use this:
Quadro.#t=Math.atan2(dy,dx);
From Wikipedia:
The Cartesian coordinates x and y can be converted to polar
coordinates r and φ with r ≥ 0 and φ in the interval (−π, π] by: