Fastest way to interpolate between radians? [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So, I have radian angles without any range (-inf to +inf basically) and I need to interpolate these as quick as possible. If there any cookie cutter way to do this?
PS: I only need to interpolate 2 values at a time, so a+f*(b-a) basically
PPS: the output does NOT have to be in any specific range (-PI to PI or 0 to 2PI)
PPPS: The specific problem is how to do the wrapping of the values around -PI/+PI and their multiples most efficiently

BETTER Actually forget what I wrote first. You can simply do:
template<typename K>
K lerpAngle(K u, K v, K p) {
return u + p*wrapMP(v - u);
}
where wrapMP moves an angle to the interval [-pi|+pi]. Both input u and v can be any radian angle and the result will also not be in a specific interval.
The idea is actually quite simple. Move your point of view to the point u such that u=0. Now v can be arbitrary as angles are not normalized, but we just wrap the distance v-u = v to [-pi|+pi] and walk by the given percentage p into that direction.
OLD (and inefficient) I wrote this code once:
template<typename K>
K lerpAngle(K u, K v, K p) {
K a = wrap2Pi(u);
K b = wrap2Pi(v);
K d = b - a;
if(d < -PI) {
b += 2*PI;
}
if(d > +PI) {
b -= 2*PI;
}
return wrap2Pi(a + p*(b - a));
}
where wrap2i moves an angle to the interval [0,2*pi[.

First, "normalize" your input angles so they're in a specific range, like (-π, π]. If you do this already, skip this part.
Then, take their difference. If the absolute value of this difference is greater than π then adjust one of the inputs by adding / subtracting 2π such that the absolute value of the difference becomes less or equal to π.
Then simply interpolate between those two values.
If the output of this interpolation should always be in the range (-π, π] again (note: it probably doesn't have to, depending on where you need this angle), then add / subtract 2π again if it's not.

Related

Elliptic Curve with a secant line [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Currently I was trying to solve a problem with the condition below:
1. giving an elliptic curve y^2 = x^3 + ax + b
2. the user will input a, b and two points that exactly on the curve.
To put it simply, what I really need to do is make a secant line of the graph with the two points P and Q and try to check that if there is any point of intersection existing. If it exists, get the x and y of this point. I'm so struggled to solve this problem. Could someone give me some hints?
I'd homogenize this to x^3 + axz^2 + bz^3 - y^2z = 0 and points P = [Px : Py : Pz] and Q = [Qx : Qy : Qz]. Then any point R = λP + μQ with (λ, μ) ≠ (0, 0) lies on the line spanned by P and Q. If you wanted to avoid homogenizations, you'd require λ+μ=1 but that usually leads to divisions I'd rather avoid until the very end.
Plug the resulting coordinates of R into the homogenized equation of the elliptic curve, and you obtain a homogeneous cubic equation in λ and μ, i.e. something like
αλ³ + βλ²μ + γλμ² + δμ³ = 0
with the α, β, γ and δ depending on your a, b, P, Q. For μ=0 you get a coordinate vector which is a multiple of P, and as homogeneous coordinates identify multiples, you get point P itself, which lies on the curve. So μ=0 must satisfy the equation, hence you know α=0 even before you compute it. Likewise λ=0 represents Q so δ=0 if that point lies on the curve. You are left with
(βλ + γμ)λμ = 0
The trailing two factors encode the two known intersections I just mentioned. The parenthesis is the third intersection, the one you need. Now simply pick λ=γ and μ=−β to obtain a simple expression for the third point of intersection.
If you want to dehomogenize at the end, simply divide the first two coordinates of the resulting homogeneous coordinate vector by the third.
If I didn't mess up my sympy computation, you have
β = 3*Px^2*Qx + 2*Px*Pz*Qz*a - Py^2*Qz - 2*Py*Pz*Qy + Pz^2*Qx*a + 3*Pz^2*Qz*b
γ = 3*Px*Qx^2 + 2*Pz*Qx*Qz*a - Pz*Qy^2 - 2*Py*Qy*Qz + Px*Qz^2*a + 3*Pz*Qz^2*b
Which is expectedly very symmetric in P and Q. So essentially you just need a single function, and then you get β=f(P,Q) and γ=f(Q,P).
In C++ and with the whole homogenization / dehomogenization in place:
inline double f(double Px, double Py, double Qx, double Qy, double a, double b) {
return 3*Px*Px*Qx + 2*Px*a - Py*Py - 2*Py*Qy + Qx*a + 3*b;
}
std::pair<double, double> third_intersection(double Px, double Py, double Qx, double Qy, double a, double b) {
double beta = f(Px, Py, Qx, Qy, a, b);
double gamma = f(Qx, Qy, Px, Py, a, b);
double denominator = gamma - beta; // Might be zero if line PQ is an asymptote!
double x = (gamma*Px - beta*Qx) / denominator;
double y = (gamma*Py - beta*Qy) / denominator;
return std::make_pair(x, y);
}

How to write a log base 10 function in c++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I know that it may seem a duplicate question, but I could not find my answer in previous questions.
I mean how to write a log base 10 function by simple loops and not using built in log function in c++.
The easiest way is to calculate the natural logarithm (ln) with a Taylor series. Once you have found the natural logarithm, just divide it by ln(10) and you get the base-10 log.
The Taylor series is quite simple to implement in C. If z is the number for which you are seeking the log, you just have to loop a few iterations multiplying an accumulator by (z-1) each time. To a limit, the more iterations you run, the more accurate your result will be. Check it a few times against the libC log10() version until you are happy with the precision.
This is a "numeric approach". There are other numeric solutions to finding the logarithm of a number which can give more accurate results. Some of them can be found in that Wikipedia link I gave you.
Assuming by "log base 10" you mean "the number of times n can be divided by 10 before resulting in a value < 10":
log = 0;
// Assume n has initial value N
while ( n >= 10 ) {
// Invariant: N = n * 10^log
n /= 10;
log += 1;
}
You'll get faster convergence with Newton's Method. Use something like this (hand written not compiled or tested uses f(r) = 2**r - x to compute log2(x) ):
double next(double r, double x) {
static double one_over_ln2 = 1.4426950408889634;
return r - one_over_ln2 * (1 - x / (1 << static_cast<int>(r)));
double log2(double x) {
static double epsilon = 0.000000001; // change this to change accuracy
double r = x / 2;. // better first guesses converge faster
double r2 = next(r, x);
double delta = r - r2;
while (delta * delta > epsilon) {
r = r2;
r2 = next(r, x);
delta = r - r2
}
return r2;
}
double log10(double x) {
static double log2_10 = log2(10);
return log2(x) / log2_10;
}

How can I do this more elegantly? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have a 2D point A inside the [0,1]² square.
The square is divided into 9 subsquares (of equal dimensions)
http://www.noelshack.com/2015-23-1433689273-capture.png
I want to know which subsquare the point A belongs to.
I can do a if elseif else on the first coordinate, then inside each branch, another if else if else on the second coordinate.
There is a lot of code repeating (the check on the second coordinate)
Is there a better way ?
The trouble is, it is not clear what your 2D point is, what you want the sub-square value as, etc. So a definitive answer is difficult. But anyway, I will make some assumptions and see if I am right about what you are asking...
Assuming you had a point A with a coordinate such as:
float point[2] = {0.1224, 0.4553}
Then to work out where it is inside the square you can do some simple maths:
float x = point[0] * 3;
float y = point[1] * 3; //Multiply both by 3
int xIdx = floor(x);
int yIdx = floor(y); //Floor the result - this gives a number 0 to 2
int cell = yIdx * 3 + xIdx + 1; // Calculate the cell index (based on your diagram)
Now you could generalise this for any point - for example the point might be (1.23343, 2.6768) - by simply removing the integer part from the point - leaving a number between 0 and 1. The integer part would be the super cell, and the fractional part would be converted into the sub cell as above.

Algorithm to generate a point grid out of a plane equation [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a plane equation in 3D-space: ax + by + cz + d = 0 and I want to fill this plane within a given radius from a specific point on the plane with regulary distributed points. It seems to me, that there should be a mathematical elegant answer, but I fail to see it. Answer in C++ or pseudo-code will be better.
I'll assume you have a reasonably good 3d vector class, and call it vec3 in the answer. The first thing you need is a vector in your plane. There are a few ways to generate one given the normal-plane equation, but I prefer this one:
vec3 getPerpendicular(vec3 n)
{
// find smallest component
int min=0;
for (int i=1; i<3; ++i)
if (abs(n[min])>abs(n[i]))
min=i;
// get the other two indices
int a=(min+1)%3;
int b=(min+2)%3;
vec3 result;
result[min]=0.f;
result[a]=n[b];
result[b]=-n[a];
return result;
}
This construction guarantees that dot(n, getPerpendicular(n)) is zero, which is the orthogonality condition, while also keeping the magnitude of the vector as high as possible. Note that setting the component with the smallest magnitude to 0 also guarantees that you don't get a 0,0,0 vector as a result, unless that is already your input. And in the case, your plane would be degenerate.
Now to get your base vectors in the plane:
vec3 n(a,b,c); // a,b,c from your equation
vec3 u=normalize(getPerpendicular(n));
vec3 v=cross(u, n);
Now you can generate your points by scaling u and v and adding it to the vector you got on the plane.
float delta = radius/N; // N is how many points you want max in one direction
float epsilon=delta*0.5f;
for (float y=-radius; y<radius+epsilon; radius+=delta)
for (float x=-radius; x<radius+epsilon; radius+=delta)
if (x*x+y*y < radius*radius) // only in the circle
addPoint(P+x*u+y*v); // P is the point on the plane
The epsilon makes sure your point count is symmetric and you don't miss the last point on the extremes.

given a triangle and a segment, find third point which would create a similar triangle [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I've seen similar questions asked, but I find the explanations still somewhat difficult.
I have a triangle with its 3 vertices given in (x,y). I am also given a segment of two points. I want to place a third point around the segment so that it completes a triangle with similar shape to the original triangle. This new triangle might not be the same size, but all the angles would be the same. How would I find this third point?
I have gotten as far as finding the length of each segment and the angles of the triangle, but I'm kind of stuck.
I saw the following post and tried to implement the code discussed with no luck on getting the correct coordinates..
Calculating the coordinates of the third point of a triangle
Edit: Sorry about that, I forgot to specify that I know that I want to place my third point close to one of the ends of the segment. Example: I have triangle with verticies A, B, and C. I have a segment DE (created by points D and E), where DE is similar to AB. I want to place point F at a position so that AD is similar to EF and AC is similar to DF.
For the sake of being specific, suppose your original triangle has vertices A, B, and C. The line segment has end points D and E. Furthermore, you want DE to correspond to AB. The problem is then to find a point F such that triangle DEF is similar to triangle ABC. I hope that's what you're trying to solve, because that's what I'm going to give you as a solution. Explaining the solution is going to be a lot longer than coding it. :)
I think you can do all this with vector arithmetic, without using angles and trig functions. Let all points be represented by their x and y coordinates in some shared coordinate system. (If you don't know vector arithmetic, see the appendix below.)
First, we'll imagine a local coordinate system u-v with A as the origin and AB parallel to the u axis; the v axis is perpendicular to u; we'll nail down which direction is positive in a second. Now, even though AB is the side of the triangle, from now on we'll think of it as a vector from A to B. It can be computed in the x-y system as AB = (B[x] - A[x], B[y] - A[y]). The same goes for all other point pairs. Individual points will also be vectors in the x-y system. A unit vector in the x-y system along the u axis is given by:
u = (u_x, u_y) = AB / ‖AB‖
A unit vector along the v axis is just:
v = (-u_y, u_x)
(We could also have used (u_y, -u_x).) We will now compute the vector components of AC in the u-v system:
AC_u = (AC_x * u_x, AC_y * u_y) // = (AC ∙ u)
AC_v = ‖AC - AC_u * u‖
Now we imagine another local coordinate system, r-s, with origin at D and r axis along DE. The unit vectors along r and s in the x-y system are:
r = (r_x, r_y) = DE / ‖DE‖
s = (-r_y, r_x)
We can scale the u-v components of AC by the ratio ‖DE‖ / ‖AB‖ to get r-s components of DF:
DF_r = AC_u * ‖DE‖ / ‖AB‖
DF_s = AC_v * ‖DE‖ / ‖AB‖
Finally, we just need to add everything together:
F = D + DF_r * r + DF_s * s
(Recall that D, r, and s are vectors.) That's it. Although the post is long, there are only a dozen or so lines of code (each vector calculation step takes one lines for each component) plus another handful for a function to compute the norm of a vector.
APPENDIX: Vector arithmetic
Vectors in an x-y coordinate system are ordered pairs of numbers: (x, y). Two vectors A and B can be added or subtracted by adding or subtracting their components: A ± B = (A_x ± B_x, A_y ± B_y). A vector can be multiplied by a number (also called a scalar) by multiplying each vector component by the scalar: q*A = (q*A_x, q*A_y). Division by a scalar is just multiplication by the inverse of the scalar. The norm of a vector A (also called its length) is written ‖A‖; it can be computed using the Pythagorean theorem: ‖A‖ = sqrt(A_x * A_x + A_y * A_y). A unit vector is a vector with norm = 1. The dot product of two vectors is the sum (a simple number) of the products of corresponding components: A ∙ B = A_x*B_x + A_y*B_y. Note that the dot product of a vector with itself is the square of its norm. An important identity about the dot product is: A ∙ B = ‖A‖ * ‖B‖ * cos(α) where α is the angle between A and B. A corollary is that the dot product of two non-zero vectors is zero exactly when the vectors are perpendicular to one another.