Given a N-dimensional hyperplane and a N-dimensional hyper rectangle represented by its min point and max point, how to determine if they intersect?
A naive method by computing the intersection between edges of the hyper rectangle and the hyperplane gives a O(2^N) time complexity.
I wonder if this task can be finished in a more efficient way.
Related
I need to quickly find the k nearest points to a plane (or hyperplane) in 3 (or more) dimensions. Is there a fast way to perform this search, using some sort of clever data structure (similar to how a kd-tree works for k nearest neighbors)?
I know I can rotate the plane and all the points so that the plane is orthogonal to one of the axes, then measure the distance of each point to the plane by simply using the ordinate in that axis. However, the time complexity of this brute force approach is O(N), where (N) is the number of points. Since I have to find the k nearest neighbors for a large number of planes and a large number of points, I need to find a faster algorithm if possible.
I think you can simply use any spatial data structure (kd-tree, R-tree, ...) that supports custom distance functions. You should be able to define a distance function that simply uses the distance to the plane instead of distance to a center point.
How to calculate this distance is described by #Spektre.
I have no idea how that scales, because it may depend on the kNN search algorithm used by the implementation.
However, I believe the standard algorithm (Hjaltason and Samet: "Distance browsing in spatial databases.") should at least be better than O(n).
In case you are using Java, the R-Tree, Quadtree and PH-Tree indexes in my TinSpin library all use this algorithm.
measure the distance by using dot product with hyper plane normal... So let:
n - be the hyperplane normal unit vector
p0 - be any point point on the hyperplane
p[i] - be i-th point from your pointcloud i={ 0,1,2...n-1 }
then the distance to hyperplane plane is:
d = |dot( p[i] - p0 , n )|
as you can see no need to transform/align anything and its O(1) without any expensive operations. I expect that any pre sorting of points or using clever structures will be slower than this in most cases...
Now you got 2 options either compute the d for each point and then quick sort which leads to O(n.log(n)) time and O(n) space complexity.
Or remember k closest points on the run leading to O(k*n) time and O(k) space.
So if k is small (k < log(n)) or you have not enough memory to spare use second approach otherwise use first one ...
Assume a Rope of a given length and a given stiffness (that means a minimum bending radius). Both ends are fixed at a given point in a given direction (angle) on a plane e.g. with some clamps. The rope is loose and lays in one ore more loops. It has to lay flat on the plane. No three-dimensional loops are allowed. It can lay in many different configurations depending on how loose the rope is, see image (sorry for my poor drawing).
I'm interested in the area of the plane that can be occupied by the rope (red on the image).
How can I model that in order to calculate that area?
The constraints are:
Length of the rope
minimum bending radius
Coordinates and angles of both ends of the rope
the rope has to lay flat on the plane (no 3D-loops, just 2d)
Hint:
My intuition tells me that the two extreme configurations will be such that the minimum curvature will be achieved at both endpoints on a certain length, and in between a circular arc of a higher radius, i.e. three arcs, with G1 continuity (a G1 discontinuity would be like a null radius).
You can construct them by drawing two circles of the minimum radius, tangent to the directions at the endpoints. Then the third circle will be tangent to these, but with a radius such that the sum of the arcs equals the rope length. The contact points will be symmetrical with respect to the mediatrix of the two endpoints, so that you can compute the unknown radius as a function of a single angle, and solve for the known total length.
Is there a spatial lookup grid or binning system that works on the surface of a (3D) sphere? I have the requirements that
The bins must be uniform (so you can look up in constant time if there exists a point r distance away from any spot on the sphere, given constant r.)†
The number of bins must be at most linear with the surface area of the sphere. (Alternatively, increasing the surface resolution of the grid shouldn’t make it grow faster than the area it maps.)
I’ve already considered
Spherical coordinates: not good because the cells created are extremely nonuniform making it useless for proximity testing.
Cube meshes: Less distortion than spherical coordinates, but still very difficult to determine which cells to search for a given query.
3D voxel binning: Wastes the entire interior volume of the sphere with empty bins that will never be used (as well as the empty bins at the 6 corners of the bounding cube). Space requirements grow with O(n sqrt(n)) with increasing sphere surface area.
kd-Trees: perform poorly in 3D and are technically logarithmic complexity, not constant per query.
My best idea for a solution involves using the 3D voxel binning method, but somehow excluding the voxels that the sphere will never intersect. However I have no idea how to determine which voxels to exclude, nor how to calculate an index into such a structure given a query location on the sphere.
† For what it’s worth the points have a minimum spacing so a good grid really would guarantee constant lookup.
My suggestion would be a variant of the spherical coordinates, such that the polar angle is not sampled uniformly but instead the sine of this angle is sampled uniformly. This way, the element of area sinφ dφ dΘ is kept constant, leading to tiles of the same area (though variable aspect ratio).
At the poles, merge all tiles in a single disk-like polygon.
Another possibility is to project a regular icosahedron onto the sphere and to triangulate the spherical triangles so obtained. This takes a little of spherical trigonometry.
I had a similar problem and used "sparse" 3D voxel binning. Basically, my spatial index is a hash map from (x, y, z) coordinates to bins.
Because I also had a minimum distance constraint on my points, I chose the bin size such that a bin can contain at most one point. This is accomplished if the edge of the (cubic) bins is at most d / sqrt(3), where d is the minimum separation of two points on the sphere. The advantage is that you can represent a full bin as a single point, and an empty bin can just be absent from the hash map.
My only query was for points within a radius d (the same d), which then requires scanning the surrounding 125 bins (a 5×5×5 cube). You could technically leave off the 8 corners to get this down to 117, but I didn't bother.
An alternative for the bin size is to optimize it for queries rather than storage size and simplicity, and choose it such that you always have to scan at most 27 bins (a 3×3×3 cube). That would require a bin edge length of d. I think (but haven't thought hard about it) that a bin could contain up to 4 points in that case. You could represent these with a fixed-size array to save one pointer indirection.
In either case, the memory usage of your spatial index will be O(n) for n points, so it doesn't get any better than that.
I am trying to implement a Z-buffer (depth buffer) for a polygon rasterization algorithm. All of my polygons are triangles and I understand that three points (x,y,z) that make up a triangle also form a plane. If I have the (x,y,z) values of the verices, how would I calculate the depth of every position on the face of the triangle?
In OpenGl or WebGl a z-buffer is applied just after rasterization i.e. for each pixel, not for each vertex of a triangle. In this case you need to save z-value for each pixel and then just get a pixel this max z-value. This is done automatically in pipeline.
If you wanna calculate a z-buffer just for vertices you need your own algorithm. For example just getting max z-value of triangle's vertices and sort triangles by this value.
Also check this link for more info.
Looking at Convert a quadratic bezier to a cubic?, I can finally understand why programming teachers always told me that math was so important. Sadly, I didn't listen.
Can anyone provide a more concrete - e.g., computer-language-y - formula for converting a quadratic curve to a cubic? Understanding that there's some rounding errors possible, which is fine.
Given a quad curve represented by variables:
StartX, StartY
ControlX, ControlY
EndX, EndY
And desiring StartX, StartY and EndX, EndY to remain the same, but to now have Control1X, Control1Y and Control2X, Control2Y of a cubic curve.
Is it...
Control1X = StartX + (.66 * (ControlX - StartX))
Control2X = EndX + (.66 * (ControlX - EndX))
With the same essential functions used to calculate Control1Y and Control2Y?
Your code is right except that you should use 2.0/3.0 instead of 0.66.
You avoid most rounding errors by using
Control1 = (Start + 2 * Control) / 3
Control2 = (End + 2 * Control) / 3
Note that line segments are also convertible to cubic Bezier curves using:
Control1 = Start
Control2 = End
This can be handy when converting a complex path mixing various types of curves (linear, quadratic, cubic).
There's also a basic transform for converting elliptic arcs to cubic (with some minor unnoticeable errors): you just have to split at least the arc on elliptic quadrans (cutting the ellipse first on the two orthogonal axis of symetries, or on arbitrary orthogonal axis passing through the center if the ellipse is a circle, then representing each arc; when the ellipse is a circle, the two focal points are confused on the same point, the center of the circle, so you can use any direction for one of the orthogonal axis).
Many SVG renderers do that by adding an additional split on octants (so that you get also precise position not only for points where the two main axis are passing through, but also for two diagonal axis which are bissecting (when the ellipse is a circle) each quadrant (when the ellipse is not a circle, assimilate it as a circle flattened with a linear transform along the small axis only, you do the same computation), because octants are also quite precisely positioned:
cos(pi/4) = sin(pi/4) = sqrt(2)/2 ≈ 0.71, and because this additional splitting will allow precise rendering of tangents on points crossing the diagonals at 45 degrees of the circle.
A full ellipse is then converted to 8 cubic arcs (i.e. 8 points on ellipse and 16 control points): you'll almost not notice the difference between elliptical arcs and these generated cubic arcs
You can create an algorithm that uses the same "flattening error" computed when splitting a Bezier to a list of linear segments, which are then drawn using the classic fast Bresenham algo for line segments; a "flattenning" algorithm just has to measure the relative deviation of the sum of lengths of the two straight segments joining the two focal points of the ellipse to any point of the generated cubic arcs, as this sum is constant on any true ellipse: if you make this measurement on the generated control points for the cubic arcs, the difference should be below a given percentage of the expected sum, or within an absolute distance precision, and can be used to create better approximation of control points with a simple linear formula so that these added points will be on the real ellipse.
Such transform of arbitrary paths is useful when you want to derive other curves from the path, notably the curves of "buffers" at a given distance, notably when these paths must be converted to "strokes" with a defined "stroke width": you need to compute two "inner" and "outer" curves and then concentrate on how to converting the miters/buts/squares/rounded corners, and then to cut long miters at a convenient distance (matching the "miter limit" factor times the "stroke width").
More advanced renderers will also use miters represented by tangent circles when there's a corner between two arcs instead of two segments (this is useful for drawing cute geographic maps)...
Converting an arbitrary path mixing segments, elliptic and bezier arcs to only cubic arcs is a necessary step to compute precise images without excessive defects visible when zooming in. This is then necessary when your "stroke" buffers have to take some effects (such as computing dashes), and then enhancing the result with semi-transparent pixels or subpixels to smooth the rendered strokes (smoothing is easy to computez only when everything has been flattened to line segments, and alsos may be simpler to develop if it only has to manage paths containing only cubic beziers: it can easily be parallelized if needed and accelerated by hardware). Bezier arcs are always interesting because drawing them is fast and requires only basic arithmetics, and the time needed to draw them is proportional to the length of the curve with every point drawn with the same accuracy level.
In summary, all curves are representable by cubic Bezier arcs with a maximum measurable deviation allowed (you can set this maximum deviation to one half pixel, or one subpixel if you first scale up the measurement grid for half-toning or subpixel shading, and then represent accurately every curve with a reasonnaly fast rendering, and get accurate rendering at any zoom level with curves smoothed everywhere, including with half-toning or transparency levels when finally drawing the linear strokes with the classic Bresenham algorithm using fast integer-only arithmetics). These rendered curve will all have the correct tangeants everywhere, without any unexpected angles visible on approximation points, and the remaining control points in the approximation will make also a good smooth rendering of the curvature everywhere (i.e. radius of the tangeant circle), so you can use this approximation as well to derive other measurements such as acceleration, inertial forces, or magnetic effects of paths of charged particles).
If you ever need higher precision, use Bezier arcs with degree 4 (i.e. with 3 control points between points on curve) to get smoothed derivation at a supplementary degree (e.g. gradients of forces), or just split the cubic arcs with additional steps further, until the derivation is smooth enough (but using degree-4 Bezier arcs requires much less points curves and less control points for the same accuracy tolerances, than when using cubic Bezier only).