Three.js. Finding neighboring vertices within radius - javascript

I've been looking for a way to find the the vertices within a certain radius from a given point. One way to this is brute force. After selection of a point (raypicking), loop over all vertices, check whether it is within a set radius and voila. However, this tends to get quite slow for models with lots of vertices.
What I would want to do is use raypicking to select a point on the model. This would give me the face this point is on. Then from that face I can get the vertices belonging to that face. These vertices can be "shared" over faces. This might allow me to forward search from this point, flagging visited vertices and stop whenever the distance reaches the set maximum (radius). However, from what I can see from a dump of the geometry I can get the vertices belonging to a face directly, but there's no way to get the faces that a vertex belongs to. That is without preprocessing. Am I right here, or did I miss something?

Related

How to implement rolling a ball on a sphere in terms of matrices?

Target:
It is necessary to create two spheres, one of which can be rolled over the surface of the other with the mouse, and implement a camera that can be moved around these balls using the keyboard.
Implementation:
I started a matrix that stores the current state of the rotation of the rolling ball. When the user drags, I get a series of mouse move events, and each time I move, I calculate how many degrees around the current X and Y, as the user sees them, the rotation has changed. Then I calculate a matrix that represents these two rotations and multiply the original sphere rotation matrix by it in reverse order - the reverse order is necessary because the rotation occurs from the point of view of the camera, and not from the point of view of model space.
Problem:
But with such an implementation, the second sphere will not change the point of contact with the first sphere (it will, as it were, slide along it), how can one analytically implement the rotation of the point of contact of the balls in terms of matrices?
Here is the code if anyone is interested: https://github.com/AndrewStrizh/spheres-with-webGL
What you need is to be able to control rotation of your sphere around two (or more) different rotation pivots.
A proper way to deal with complex transformations is to implement hierarchical transformations:
http://web.cse.ohio-state.edu/~wang.3602/courses/cse3541-2019-fall/05-Hierarchical.pdf
In this case, you can control the rotation of the sphereB around the sphereA by making the sphereB a child of an third invisible object - call it Locator - located at the center of the sphereA. With proper implementation of hierarchical transformations, rotating the Locator will also rotate the sphereB around this Locator (so, around the sphereA). In the same time, you can also apply a rotation of the sphereB around its own center, making it spinning.
In practice, implementing true hierarchical transformations require to implement a scene graph, with proper nodes traversal, etc. But the main idea is that every object have what is called a local transform matrix, and world transform matrix. The local transform matrix hold only the own transformation of that particular object (locally to its own origin), while the world transform matrix is the final matrix, sum result of all the hierarchical transformations (from parents) applied to this object.
The world transform matrix is the one used as "model" matrix, to be multiplied with the view and projection matrices. World and local transform matrices of nodes are computed like this (pseudocode):
node.worldMatrix = node.localMatrix * node.parent.worldMatrix;
Knowing that, since you only need three objects and two hierarchical transformations, you don't have to implement a whole scene graph, you only need to simulate this principle by multiplying proper matrices to reproduce the desired behavior.

Algorithm to decompose Polygons into lineStrings (Headlands from Plots)

Consider the following polygon (an agricultural plot)
From this polygon, I would like to extract the "headlands" of the plot, being the consecutive lines (sides) of the polygon (Wikipedia) used for turning on the field. While often only the rows running perpendicular to the lay of the field are considered, I need all sides of the polygon.
Here, a consecutive line means any set of coordinates, where the angle between any two coordinates of the set is not larger than a value X (e.g 30 degrees).
For the given example, the resulting headlands should look like the following:
I wrote a small algorithm trying to accomplish this, basically checking the angle between two coordinates and either pushing the given coordinate to the existing lineString if the angle is below X degrees or creating a new lineString (headland) if not.
Check out the following Gist
However, in some cases corners of a field are rounded, therefore may consist of many coordinates within small distances of each other. The relative angles then may be less than the value X, even though the corner is too sharp to actually be cultivated without turning.
In order to overcome that issue, I added an index that increases whenever a coordinate is too close for comparison, so that the next coordinate will be checked against the initial coordinate. Check out the following Gist.
This works for simple plots like the one in the example, however I am struggling with more complex ones as the following.
Here, the bottom headland is recognised as one lineString together with the headland on the right, even though optically a sharp corner is given. Also, two coordinates in the upper right corner were found to be a separate headland even though they should be connected to the right headland. The result should therefore yield in the following:
What I would like to know is if there is an approach that efficiently decomposes any polygon into it's headlands, given a specific turning angle. I set up a repo for the code here, and an online testing page with many examples here if that helps.

Threejs draw a shape from just points

Given a list of Vector3s in no order, I would like to create an ordering of the elements such that when I draw a Shape from those points, I will be outlining the shape without ever going across its face.
How would you do this? I think the first thing is to always pick the point closest to you, but what if more than one point have exactly the same distance from a point?
Let's call the point we're on x, and a potential "neighbor" (point whose distance to x is minimal) y where there can be multiple ys.
I've thought about these two approaches:
Find the center of mass by averaging out the positions of the points, then make sure that going from x to y never goes through the center. This approach has many problems like 1. it's not guaranteed to cross the CoM or 2. imagine a fidget spinner with just two circles, and one much smaller than the other. When tracing the smaller bit, the center of mass is never crossed (or come close to), but we might still ran into problems
Randomly pick any other three points, and make sure that y is not within the triangle created. But there are cases where y is the correct choice, but still falls within the triangle (imagine a shape one of whose edge is created by two tangent circles).
Any help would be much appreciated!

Three.js - Editing faces

I thought I'd ask this here because I can't find any information anywhere (SO or the three.js documentation) - How do you get the average x,y,z coordinates of a specific face? Or at the very least, is there a way to get the x,y,z coordinates of the three vertices that make up a face? And then use those to calculate the average?
So far I have
var fLength = plane.geometry.faces.length;
for (var i = 0; i < fLength; i++) {
var f = plane.geometry.faces[i];
//How do I get the x,y,z of the current/i face?
//Is there a way to move this face?
//Is there a way to extrude this face? Or do -anything- with it for that matter?
}
Additionally, are there any methods for moving a face apart from moving the vertices? What about extruding faces? I realize it's quite a few questions however the process for all of this seems a little unclear to me...
Each Three.js Face3 contains properties a, b and c. Those are the indices into the vertex array of the same geometry object. For example, use
v1 = plane.geometry.vertices[f.a];
to get the Vector3 representing the position of the first vertex in the face.
Three.js doesn't offer much convenience methods for modifying the geometry of an existing object. Like the underlying graphics API's, its focus is on quickly composing and displaying a scene of mostly static objects (vertex shader operations aside).
You'll have to manually adjust the individual vertice that make up the faces (and set the correct dirty flags), or even rebuild faces if your modifications effectively modify edges. Depending on your use case, your operation might be simpler to perform using a vertex shader.
The point is, the topic of building and modifying geometry quickly gets pretty hairy. If you need any help there, make sure to ask a specific question, outlining your desired operation on the geometry.

how to "sort" polygons 3d?

I am still working on my "javascript 3d engine" (link inside stackoverflow).
at First, all my polygons were faces of cubes, so sorting them by average Z was working fine.
but now I've "evolved" and I want to draw my polygons (which may contain more than 4 vertices)
in the right order, namely, those who are close to the camera will be drawn last.
basically,
I know how to rotate them and "perspective"-ize them into 2D,
but don't know how to draw them in the right order.
just to clarify:
//my 3d shape = array of polygons
//polygon = array of vertices
//vertex = point with x,y,z
//rotation is around (0,0,0) and my view point is (0,0,something) I guess.
can anyone help?
p.s: some "catch phrases" I came up with, looking for the solution: z-buffering, ray casting (?!), plane equations, view vector, and so on - guess I need a simple to understand answer so that's why I asked this one. thanks.
p.s2: i don't mind too much about overlapping or intersecting polygons... so maybe the painter's algorthm indeed might be good. but: what is it exactly? how do I decide the distance of a polygon?? a polygon has many points.
The approach of sorting polygons and then drawing them bottom-to-top is called the "Painter's algorithm". Unfortunately the sorting step is in general an unsolvable problem, because it's possible for 3 polygons to overlap each other:
Thus there is not necessarily any polygon that is "on top". Alternate approaches such as using a Z buffer or BSP tree (which involves splitting polygons) don't suffer from this problem.
how do I decide the distance of a polygon?? a polygon has many points.
Painter's algorithm is the simplest to implement, but it works only in very simple cases because it assumes that there is only a single "distance" or z-value for each polygon (which you could approximate to be the average of z-values of all points in the polygon). Of course, this will produce wrong results if two polygons intersect each other.
In reality, there isn't a single distance value for a polygon -- each point on the surface of a polygon can be at a different distance from the viewer, so each point has its own "distance" or depth.
You already mentioned Z-buffering, and that is one way of doing this. I don't think you can implement this efficiently on a HTML canvas, but here's the general idea:
You need to maintain an additional canvas, the "z-buffer", where each pixel's colour represents the z-depth of the corresponding pixel on the main canvas.
To draw a polygon, you go through each point on its surface and draw only those points which are closer to the viewer than any previous objects, as indicated by the z-buffer.
I think you will have some ideas by investigating BSP tree ( binary spaces partition tree ), even if the algo will require to split some of your polygon in two.
Some example could be find here http://www.devmaster.net/articles/bsp-trees/ or by google for BSP tree. Posting some code as a reply is, in my opinion, not serious since is a complex topic.

Categories

Resources