Ray-Plane Intersection - raytracing

I'm having a hard time following the ray-plane intersection described in the following page.
SIGGRAPH Ray-Plane Intersection
Here is my understanding.
The plane is described as Ax + By + Cz + D = 0
or
The Vector ( A, B, C, D ), Where A, B, C define a normal plan. If A, B, and C define a unit normal, then the distance from the origin [0, 0, 0] to the plan is D.
My question is shouldn't D be a vector? Since it represents the distants between two points. I guess I just don't understand how you can represent the distance between to points as a non vector.
Any help is much appreciated.

Distance between two points is ALWAYS a scalar, a single number. Think of the vectors as points in space, right? So, when you say distance between two vectors, you are finding the distance between those two points which is a number. Distance between two vectors is the magnitude of the difference vector of the two vectors. So, you subtract the 2 vectors, get the difference vector and find its magnitude. That is your distance which is a SCALAR and NOT a vector.

Distance is a scalar value, not a vector. It is, in fact, the length of a vector.
You can think of a vector as a set of values describing a point in space in relation to the origin. In R3, you need a minimum of 3 pieces of information to describe the location of that point. These pieces of information give you a direction and a distance.
If you were to tell me that a city is 50 miles away, that would be you describing a distance. Of course, you will not have told me which direction that city was. When you give me 2 pieces of information, you have given me a vector, as opposed to scalar value.
Also recall the formula for distance:
D = sqrt(x^2 + y^2 + z^2)
Scalar value ;)

Related

Correct implementation of weighted K-Nearest Neighbors

From what I understood, the classical KNN algorithm works like this (for discrete data):
Let x be the point you want to classify
Let dist(a,b) be the Euclidean distance between points a and b
Iterate through the training set points pᵢ, taking the distances dist(pᵢ,x)
Classify x as the most frequent class between the K points closest (according to dist) to x.
How would I introduce weights on this classic KNN? I read that more importance should be given to nearer points, and I read this, but couldn't understand how this would apply to discrete data.
For me, first of all, using argmax doesn't make any sense, and if the weight acts increasing the distance, than it would make the distance worse. Sorry if I'm talking nonsense.
Consider a simple example with three classifications (red green blue) and the six nearest neighbors denoted by R, G, B. I'll make this linear to simplify visualization and arithmetic
R B G x G R R
The points listed with distance are
class dist
R 3
B 2
G 1
G 1
R 2
R 3
Thus, if we're using unweighted nearest neighbours, the simple "voting" algorithm is 3-2-1 in favor of Red. However, with the weighted influences, we have ...
red_total = 1/3^2 + 1/2^2 + 1/3^2 = 1/4 + 2/9 ~= .47
blue_total = 1/2^2 ..............................= .25
green_total = 1/1^2 + 1/1^2 ......................= 2.00
... and x winds up as Green due to proximity.
That lower-delta function is merely the classification function; in this simple example, it returns red | green | blue. In a more complex example, ... well, I'll leave that to later tutorials.
Okay, off the bat let me say I am not the fan of the link you provided, it has image equations and follows a different notation in the images and the text.
So leaving that off let's look at the regular k-NN algorithm. regular k-NN is actually just a special case of weighted k-NN. You assign a weight of 1 to k neighbors and 0 to the rest.
Let Wqj denote the weight associated with a point j relative to a point q
Let yj be the class label associated with the data point j. For simplicity let us assume we are classifying birds as either crows, hens or turkeys => discrete classes. So for all j, yj <- {crow, turkey, hen}
A good weight metric is the inverse of the distance , whatever distance be it Euclidean, Mahalanobis etc.
Given all this, the class label yq you would associate with the point q you are trying to predict would be the the sum of the wqj . yj terms diviided by the sum of all weights. You do not have to the division if you normalize the weights first.
You would end up with an equation as follows somevalue1 . crow + somevalue2 . hen + somevalue3 . turkey
One of these classes will have a higher somevalue. The class witht he highest value is what you will predict for point q
For the purpose of training you can factor in the error anyway you want. Since the classes are discrete there are a limited number of simple ways you can adjust the weight to improve accuracy

Given a convex polygon, add a point and recalculate the area

Assume you have a convex polygon P(defined by an array of points p), and a set of points S(all of them outside of P), how do you choose a point s in S such that it increases the most the area of P.
Example
I have a O(|P|) formula to calculate the area of the polygon, but I can't do this for every point in S given that
3 ≤ |P|, |S| ≤ 10^5
The big dots are the points in S
No 3 points in P u S are collinear
Given fixed points p = (px, py), q = (qx, qy) and a variable point s = (sx, sy), the signed area of the triangle ∆pqs is
|px py 1|
½ |qx qy 1|
|sx sy 1| ,
which is a linear polynomial in sx, sy.
One approach is to compute cumulative sums of these polynomials where p, q are the edges in clockwise order. Use binary search to find the sublist of edges that remain in the convex hull with a given point s, add the polynomials, and evaluate for s.
You have a method to calculate the exact area that is added by a point n (and David Eisenstat posted another), but their complexity depends on the number of sides of the polygon. Ideally you'd have a method that can quickly approximate the additional area, and you'd only have to run the exact method for a limited number of points.
As Paul pointed out in a comment, such an approximation should give a result that is consistently larger than the real value; this way, if the approximation tells you that a point adds less area than the current maximum (and with randomly ordered input this will be true for a large majority of points), you can discard it without needing the exact method.
The simplest method would be one where you only measure the distance from each point to one point in the polygon; this could be done e.g. like this:
Start by calculating the area of the polygon, and then find the smallest circle that contains the whole polygon, with center point c and radius r.
Then for each point n, calculate the distance d from n to c, and approximate the additional area as:
the triangle with area r × (d - r)
plus the rectangle with area 2 × r 2 (pre-calculated)
plus the half circle with area r × π (pre-calculated)
minus the area of the polygon (pre-calculated)
This area is indicated in blue on the image below, with the real additional area slightly darker and the excess area added by the approximation slightly lighter:
So for each point, you need to calculate a distance using √ ((xn - xc)2 + (yn - yc)2) and then multiply this distance by a constant and add a constant.
Of course, the precision of this approximation depends on how irregular the shape of the polygon is; if it does not resemble a circle at all, you may be better off creating a larger simple polygon (like a triangle or rectangle) that contains the original polygon, and use the precise method on the larger polygon as an approximation.
UPDATE
In a simple test where the polygon is a 1x1 square in the middle of a 100x100 square space, with 100,000 points randomly placed around it, the method described above reduces the number of calls to the precise measuring function from 100,000 to between 150 and 200, and between 10 and 20 of these calls result in a new maximum.
While writing the precise measuring function for the square I used in the test, I realised that using an axis-aligned rectangle instead of a circle around the polygon leads to a much simpler approximation method:
Create a rectangle around the polygon, with sides A and B and center point c, and calculate the areas of the rectangle and the polygon. Then, for each point n, the approximation of the additional area is the sum of:
the triangle with base A and height abs(yn - yc) - B/2
the triangle with base B and height abs(xn - xc) - A/2
the area of the rectangle minus the area of the polygon
(If the point is above, below or next to the rectangle, then one of the triangles has a height < 0, and only the other triangle is added.)
So the steps needed for the approximation are:
abs(xn - xc) × X + abs(yn - yc) × Y + Z
where X, Y and Z are constants, i.e. 2 subtractions, 2 additions, 2 multiplications and 2 absolute values. This is even simpler than the circle method, and a rectangle is also better suited for oblong polygons. The reduction in the number of calls to the precise measuring function should be similar to the test results mentioned above.

Fastest way of calculating the projection of a polygon onto a line

Recently I have started doing some research on the SAT (Separating Axis Theorem) for collision detection in a game I am making. I understand how the algorithm works and why it works, what I'm puzzled about is how it expects one to be able to so easily calculate the projection of the shape onto different axes.
I assume the projection of a polygon onto a vector is represented by line segment from point A to point B, so my best guess to find points A and B would be to find the angle of the line being projected onto and calculate the min and max x-values of the coordinates when the shape is rotated to the angle of the projection (i.e. such that it is parallel to the x-axis and the min and max values are simply the min and max values along the x-axis). But to do this for every projection would be a costly operation. Do any of you guys know a better solution, or could at least point me to a paper or document where a better solution is described?
Simple way to calculate the projection of the polygon on line is to calculate projection of all vertex onto the line and get the coordinates with min-max values like you suggested but you dont need to rotate the polygon to do so.
Here is algorithm to find projection of point on line :-
line : y = mx + c
point : (x1,y1)
projection is intersection of line perpendicular to given line and passing through (x1,y1)
perdenicular line :- y-y1 = -1/m(x-x1) slope of perpendicular line is -1/m
y = -1/m(x-x1) + y1
To find point of intersection solve the equation simultaneously :-
y = mx + c , y = -1/m(x-x1) + y1
mx + c = -1/m(x-x1) + y1
m^2*x + mc = x1-x + my1
(m^2+1)x = x1 + my1 - mc
x = (x1-my1 - mc)/(m^2+1)
y = mx + c = m(x1-my1-mc)/(m^2+1) + c
Time complexity : For each vertex it takes O(1) time so it is O(V) where V is no of vertex in the polygon
If your polygon is not convex, compute its convex hull first.
Given a convex polygon with n vertices, you can find its rotated minimum and maximum x-coordinate in n log n by binary search. You can always test whether a vertex is a minimum or a maximum by rotating an comparing it and the two adjacent vertices. Depending on the results of the comparison, you know whether to jump clockwise or counterclockwise. Jump by k vertices, each time decreasing k by half (at the start k=n/2).
This may or may not bring real speed improvement. If your typical polygon has a dozen or so vertices, it may make little sense to use binary search.

closest lattice point type question

I can't seem to find a solution to this problem. Let's set Z^2 to be the integer lattice in R^2. Given a rational ray (meaning a vector with rational slope), is there a fast method to compute the closest lattice point to this vector in terms of orthogonal distance? Can this method be generalized to a hyperplane in R^n?
Your question does not seem well defined. How do you define the distance to a vector ?
If you're asking for the closest distance from the lattice to the line whose direction is a rational vector (as suggested by your generalization) then the answer is zero, thanks to the rationality: your direction is D = (n1/d1, n2/d2). Then, the point (d2*n1, d1*n2) is on the line.
For the smallest non-zero distance :
We can assume that d1=d2=d : D = (n1/d, n2/d) (which you can get by setting e.g. d = d1*d2). Now, the possible distances from the unit-grid lattice to the line are of the form (Z*n1 + Z*n2)/d = (Z*gcd(n1,n2))/d where Z is the set of integers. (This is a consequence of Bézout theorem). So the minimal non zero distance is gcd(n1,n2)/d where gcd(.,.) gives the greatest common divisor of two integers.

Algorithm to find the closest 3 points that when triangulated cover another point

Picture a canvas that has a bunch of points randomly dispersed around it. Now pick one of those points. How would you find the closest 3 points to it such that if you drew a triangle connecting those points it would cover the chosen point?
Clarification: By "closest", I mean minimum sum of distances to the point.
This is mostly out of curiosity. I thought it would be a good way to estimate the "value" of a point if it is unknown, but the surrounding points are known. With 3 surrounding points you could extrapolate the value. I haven't heard of a problem like this before, doesn't seem very trivial so I thought it might be a fun exercise, even if it's not the best way to estimate something.
Your problem description is ambiguous. Which triangle are you after in this figure, the red one or the blue one?
The blue triangle is closer based on lexicographic comparison of the distances of the points, while the red triangle is closer based on the sum of the distances of the points.
Edit: you clarified it to make it clear that you want the sum of distances to be minimized (the red triangle).
So, how about this sketch algorithm?
Assume that the chosen point is at the origin (makes description of algorithm easy).
Sort the points by distance from the origin: P(1) is closest, P(n) is farthest.
Start with i = 3, s = ∞.
For each triple of points P(a), P(b), P(i) with a < b < i, if the triangle contains the origin, let s = min(s, |P(a)| + |P(b)| + |P(i)|).
If s ≤ |P(1)| + |P(2)| + |P(i)|, stop.
If i = n, stop.
Otherwise, increment i and go back to step 4.
Obviously this is O(n³) in the worst case.
Here's a sketch of another algorithm. Consider all pairs of points (A, B). For a third point to make a triangle containing the origin, it must lie in the grey shaded region in this figure:
By representing the points in polar coordinates (r, θ) and sorting them according to θ, it is straightforward to examine all these points and pick the closest one to the origin.
This is also O(n³) in the worst case, but a sensible order of visiting pairs (A, B) should yield an early exit in many problem instances.
Just a warning on the iterative method. You may find a triangle with 3 "near points" whose "length" is greater than another resulting by adding a more distant point to the set. Sorry, can't post this as a comment.
See Graph.
Red triangle has perimeter near 4 R while the black one has 3 Sqrt[3] -> 5.2 R
Like #thejh suggests, sort your points by distance from the chosen point.
Starting with the first 3 points, look for a triangle covering the chosen point.
If no triangle is found, expand you range to include the next closest point, and try all combinations.
Once a triangle is found, you don't necessarily have the final answer. However, you have now limited the final set of points to check. The furthest possible point to check would be at a distance equal to the sum of the distances of the first triangle found. Any further than this, and the sum of the distances is guaranteed to exceed the first triangle that was found.
Increase your range of points to include the last point whose distance <= the sum of the distances of the first triangle found.
Now check all combinations, and the answer is the triangle found from this set with the minimal sum of distances.
second shot
subsolution: (analytic geometry basics, skip if you are familiar with this) finding point of the opposite half-plane
Example: Let's have two points: A=[a,b]=[2,3] and B=[c,d]=[4,1]. Find vector u = A-B = (2-4,3-1) = (-2,2). This vector is parallel to AB line, so is the vector (-1,1). The equation for this line is defined by vector u and point in AB (i.e. A):
X = 2 -1*t
Y = 3 +1*t
Where t is any real number. Get rid of t:
t = 2 - X
Y = 3 + t = 3 + (2 - X) = 5 - X
X + Y - 5 = 0
Any point that fits in this equation is in the line.
Now let's have another point to define the half-plane, i.e. C=[1,1], we get:
X + Y - 5 = 1 + 1 - 5 < 0
Any point with opposite non-equation sign is in another half-plane, which are these points:
X + Y - 5 > 0
solution: finding the minimum triangle that fits the point S
Find the closest point P as min(sqrt( (Xp - Xs)^2 + (Yp - Ys)^2 ))
Find perpendicular vector to SP as u = (-Yp+Ys,Xp-Xs)
Find two closest points A, B from the opposite half-plane to sigma = pP where p = Su (see subsolution), such as A is on the different site of line q = SP (see final part of the subsolution)
Now we have triangle ABP that covers S: calculate sum of distances |SP|+|SA|+|SB|
Find the second closest point to S and continue from 1. If the sum of distances is smaller than that in previous steps, remember it. Stop if |SP| is greater than the smallest sum of distances or no more points are available.
I hope this diagram makes it clear.
This is my first shot:
split the space into quadrants
with picked point at the [0,0]
coords
find the closest point
from each quadrant (so you have 4
points)
any triangle from these
points should be small enough (but not necesarilly the smallest)
Take the closest N=3 points. Check whether the triange fits. If not, increment N by one and try out all combinations. Do that until something fits or nothing does.

Resources