Get the world coordinates of a markup in Forge - autodesk-forge

I am trying to get the world coordinates( i.e. viewer coordinate) of a markups position. But I am unable to get It.
What I am doing:
In case of Arrow:-
I have drawn an arrow and I am getting its head and tail. Then I am trying to convert it to world client using viewer.clientToWorld as shown below
In Above screen shot m is my markup
Reason I am doing this is that I want to set a cutPlane in viewer which is exactly parallel to my markup.
Also suggest how can I find a plane which is parallel to the line and will be along z axis.
Thanks & Regards
Saurabh A.

viewer.clientToWorld could only get you the world positions when the client coords intersect a node (a point/part of the model).
To get world positions when the client coords are not intersecting see here

Related

How do I convert between 2D paper space coordinates world 3D coordinates for AEC models in a forge viewer?

I'm following a blog post by Petr Broz with my published views from a Revit project in BIM 360, but I was wondering how I would convert between 2D coordinates and 3D world coordinates if my published 2D view is actually just a stand-alone floor plan view without being placed on any sheet.
I was trying to get the viewport but I realized the published view doesn't have any viewport in the model. So I cannot actually use those functions in the extension for viewports. Any advise would be greatly appreciated.
Unfortunately, it doesn't support floor plan view without placing the sheet, since there is some required information missing at this moment. We are still discussing this with our engineering team.
The current working path is creating a Revit Sheet view and placing the floor plan inside, see https://www.youtube.com/watch?v=smMap86YZUY
My mistake was manually trying to convert x,y,z coordinates by dividing them with the viewport scale, thus they couldn't align with 3D world coordinates.
By providing the correct model unitscale, I could get the transform with get3DTo2DMatrix().
viewport = viewportExt.getViewports(viewer.model)[0];
viewportXform viewport.get3DTo2DMatrix(viewer.model.getUnitScale());
// From foot to millimeters
x = x* 0.00328084;
y = y* 0.00328084;
z = z* 0.00328084;
var worldPt = new THREE.Vector3(x,y,z);
worldPt.applyMatrix4(viewportXform);

How to determine start and end point of an object in autodesk forge 2d viewer

I am finding a way to pass my coordinates from 2D to 3D model.
I am stuck with an issue where I have Line/Spine which has Start and End Point.
I would like to know how can I get the Start and End point of that line which is been show in my model.
also is there any way to replace that line with my custom line using geometry (i know how to do this in 3D viewer but not sure about 2d view)
I have tried different approaches but seems like nothing is working for me
here is the reference which I was trying to follow
Link
and below is the Line/Path, what I am looking for is geometry of this line or the path of this line so that I can extract vector3 point from where the line is traveling
If you are interested in parsing the contents of a 2D model in Forge Viewer, that is also possible, using a helper class called Autodesk.Viewing.Private.VertexBufferReader. It can iterate through all the "primitives" in a 2D drawing (lines, circular arcs, elliptical arcs, etc.) and call your custom code for each one of them. Here's a blog post that explains the usage of this class: https://forge.autodesk.com/blog/working-2d-and-3d-scenes-and-geometry-forge-viewer.

Function for densest sphere packing inside a sphere

I'm trying to write a function for the densest packing of identical spheres inside a spherical boundary.
I'm thinking it will be something like spherepack(c,r,n), where:
c - centre of the boundary sphere (x,y,z coordinates)
r - radius of the boundary sphere
n - number of identical spheres to be packed inside the boundary
I want the outputs to be the x,y,z coordinates of the centre of each packed sphere. Does anyone know how this could be done?
How about what you might call the 'brute force' method. ie Model what would happen if you had a pile of n unit sized spheres and just tried packing them together in every possible close-packed configuration, and then measured the smallest containing sphere for the pack. I can imagine an algorythm for that, but it is not very programatically efficient, or mathmatically beautiful. Would it have to run fast, or just get the right answer?
Unfortunately, the assumption that close packing is densest is not correct :(

How can I find out what part of the GMSPolyline was tapped?

I have a GMSMutablePath object containing coordinates that I display visually on the screen with a GMSPolyLine. I want the user to be able to tap on a line segment (spanning two coordinates) and have the app create another node at the midpoint of that segment.
I use didTapOverlay method to get the touch event, but unfortunately that just gives the poly line as a whole. How can I find out what line segment was tapped so I know where to insert the new coordinate in the GMSMutablePath array?
I've found a work around for this, but if anyone knows how to do this properly I'd love to hear it!!
Basically, instead of drawing a single polyline to represent the path, I drew a separate line between each coordinate in the path. I subclassed polyline and added a property "positionInPath", which I set when I created the line. In didTapOverlay, I used this property to determine where to insert the new coordinate in the GMSMutablePath.
Hope that helps someone!

Around-the-world path breaking in Google Static Maps

I'm creating Google Static Maps with a path between markers and have come across certain coordinate combinations that break the path.
The path breaks in this example (markers # Beijing, SF, NY, Azores, Rome):
http://maps.google.com/maps/api/staticmap?path=color:0xff0000cc|weight:3|39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&markers=39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&maptype=terrain&sensor=false&size=640x404
And works in this example (marker # Rome removed)
http://maps.google.com/maps/api/staticmap?path=color:0xff0000cc|weight:3|39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577&markers=39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577&maptype=terrain&sensor=false&size=640x404
The cause is not crossing over the Greenwich Meridian as I initially thought. It breaks even if I add a marker before that, seemingly any a point East of the automatically calculated centerpoint of the map...but only when the path starts on the other side of -180 longitude.
To prove that, you can see that the Beijing, SF, NY, Azores, Rome path displays correctly when I set the map centerpoint to -170,35
http://maps.google.com/maps/api/staticmap?path=color:0xff0000cc|weight:3|39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&markers=39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&maptype=terrain&sensor=false&size=640x404&center=-170,35
Unfortunately, I can't programmatically set center like this because I never know the collection of points I'm going to get, and it would be next to impossible to detect that the passed points would cause a line break.
Any ideas?
First: you can calculate the center even if you don't know the collection of points (locations) at compile time: at runtime you know all the points (otherwise it would be not possible to insert the coordinates into the URL), therefore you can easily iterate over all the points and compute the center. You can computing the average of all coordinates and you get the geometric center (also called centroid): this is the easier way. Another way to do is to check the most distant pair of locations (for both, latitude and longitude) and then set the middle point as center: this requires slightly more coding (for instance to compute the longitude distance you need to take into account the you have to compute the distance in two directions, since it is possible to go 'around the world) and it has an higher complexity.
I don't go deeper in this topic because, even if you compute correctly the center of your points, this does NOT resolve the problem, and moreover the center provided automatically by the Google static map API is always correct: again the center is related to the problem, but it is not the (couse of the) problem.
An aspect that is trivial but important to keep in mind: Google static map draws a path between two locations always by considering the shortest path, i.e. by drawing the shortest straight line.
Therefore if you are in a situation where your path has to go from a location A to a location B, and the shortest path between A and B goes 'around the world' (or better, it goes out from one side of the image), then the path appears 'borken' as in maps that you have shown. In practice A and B are near the left and right margins of the map, and the map can not be centered in some point along the shortest path between A and B because of the others point of the path. And this is what happen when you remove 'Rome': without Rome the map can be centered in a way that the path is not borken.
Formally, I think that the problem appears (i.e. the path is broken), when the projection of the path on the equator is longer than 360 degree of longitudes, and the path always goes in the same direction (i.e. always west to east or always east to west).
Google static map in this situation simply adds another world map next to the first one: if you set the zoom to the minimum, you can see up to three world maps. This is really impractical for several reasons:
you can not zoom out infinitely;
if you want also insert markers into the map they will be drawn only on the 'main' map;
potentially you can have a path that goes around the world (passing in sequence from America, Europe, Asia, and America again and so on...) many times, and it would be really terrible to have so many little maps one after each other;
I googled a lot about this problem, and I didn't find any solution, there is a bug open on the bug tracker, but it is unsolved.
In my opinion the 'right' way to do is simply the following: at most one map and if a path has to goes out from one margin of the map/image, then it should appear on the opposite margin and continues to the destination, drawn on the same map.
So I found a first workaround:
you draw your path, and with the same style (line's color, etc) you also draw the path in a reversed way (Google static map allows to draws multiple paths in the same map), i.e. path=A|B|C&path=C|B|A and this will solve the problem in many situations (i.e. the path exits from one side of the image and enters from the other). Unfortunately this not works always: if you have a path that cross the image margin two consecutive times, then you lose a portion of your path
To solve this problem I found a second workaround:
- not draw simply the path and its reverse, but draw a different path for every pair of locations of the path (and reversed), i.e. for a path A->B->C then: path:A|B,path=B|C,path=C|B,path=B|A and this works always
The drawback is that in this way the URL becomes very long and the limit of 2048 characters for URLs is easily reached.
The best solution would be to compute manually the center, check manually where the path will cross the margin, and only for this portion of the path draw an additional path going between the two locations at the margin (and maybe also the reverse), but I do not think it really worth, although I do not think Google ever will solve this problem.