How would one calculate Pi using Fixed-Point Arithmetic using the leibniz series? - pi

I am trying to use an ALU and Leibniz Series to approximate pi using only integer operations ie multiplication and shifting. Does anyone know how I could program this in C?

sum = 0;
for (int i = 1; i <= 10; i++) {
sum = sum + (-1) * (1 / (2.0 * i + 1));
}
Printf("Pi=%f",4 * (sum + 1));

Related

Understanding Bezier derivation code that leads nowhere

I'm trying to convert Bezier.js implementation of calculating normals to a Shadertoy program, and the code appears to not use any of the calculated values. It needs to be for quadratic rationals as well.
I found the Javascript code a slight bit hard to follow, so I simplified it for my Shadertoy program:
vec2[3] derive(vec2[3] p)
{
vec2[3] dpoints;
int l_length = 0, j;
for (int i = 2; i > 0; --i) {
vec2[3] l;
for (j = 0; j < i; j++) {
vec2 dpt = vec2(
float(i) * (p[j + 1].x - p[j].x),
float(i) * (p[j + 1].y - p[j].y));
dpoints[l_length] = dpt;
l[l_length] = dpt; ++l_length;
}
p = l;
}
return dpoints;
}
The Bezier.js program continues to add functionality for 3d beziers, in case that has anything to do with rational beziers.
I need to make sense of the rest of the program, since I don't know the theory for calculating the normals.
To spell Pomax's answer out loud:
Only the last calculated value is used, to make a "curve" (line) from origin.
The weights are calculated as w'0 = 2(w1-w0), w'1 = 2(w2-w1).
The resulting bezier at t gives the tangent of the original bezier at t.
I hope I got this right I haven't tried this yet.

Calculate the middle of two unit length 3D vectors without a square root?

With two 3D, unit length vectors, is there a way to calculate a unit length vector in-between these, without re-normalizing? (more specifically without a square root).
Currently I'm just adding them both and normalizing, but for efficiency I thought there might be some better way.
(for the purpose of this question, ignore the case when both vectors are directly opposite)
It's not an answer to the original question; I am rather trying to resolve the issues between two answers and it wouldn't fit into a comment.
The trigonometric approach is 4x slower than your original version with the square-root function on my machine (Linux, Intel Core i5). Your mileage will vary.
The asm (""); is always a bad smell with his siblings volatile and (void) x.
Running a tight loop many-many times is a very unreliable way of benchmarking.
What to do instead?
Analyze the generated assembly code to see what the compiler actually did to your source code.
Use a profiler. I can recommend perf or Intel VTune.
If you look at the assembly code of your micro-benchmark, you will see that the compiler is very smart and figured out that v1 and v2 are not changing and eliminated as much work as it could at compile time. At runtime, no calls were made to sqrtf or to acosf and cosf. That explains why you did not see any difference between the two approaches.
Here is an edited version of your benchmark. I scrambled it a bit and guarded against division by zero with 1.0e-6f. (It doesn't change the conclusions.)
#include <stdio.h>
#include <math.h>
#ifdef USE_NORMALIZE
#warning "Using normalize"
void mid_v3_v3v3_slerp(float res[3], const float v1[3], const float v2[3])
{
float m;
float v[3] = { (v1[0] + v2[0]), (v1[1] + v2[1]), (v1[2] + v2[2]) };
m = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + 1.0e-6f);
v[0] *= m;
v[1] *= m;
v[2] *= m;
res[0] = v[0];
res[1] = v[1];
res[2] = v[2];
}
#else
#warning "Not using normalize"
void mid_v3_v3v3_slerp(float v[3], const float v1[3], const float v2[3])
{
const float dot_product = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
const float theta = acosf(dot_product);
const float n = 1.0f / (2.0f * cosf(theta * 0.5f) + 1.0e-6f);
v[0] = (v1[0] + v2[0]) * n;
v[1] = (v1[1] + v2[1]) * n;
v[2] = (v1[2] + v2[2]) * n;
}
#endif
int main(void)
{
unsigned long long int i = 20000000;
float v1[3] = {-0.8659117221832275, 0.4995948076248169, 0.024538060650229454};
float v2[3] = {0.7000154256820679, 0.7031427621841431, -0.12477479875087738};
float v[3] = { 0.0, 0.0, 0.0 };
while (--i) {
mid_v3_v3v3_slerp( v, v1, v2);
mid_v3_v3v3_slerp(v1, v, v2);
mid_v3_v3v3_slerp(v1, v2, v );
}
printf("done %f %f %f\n", v[0], v[1], v[2]);
return 0;
}
I compiled it with gcc -ggdb3 -O3 -Wall -Wextra -fwhole-program -DUSE_NORMALIZE -march=native -static normal.c -lm and profiled the code with perf.
The trigonometric approach is 4x slower and it is because the expensive cosf and acosf functions.
I have tested the Intel C++ Compiler as well: icc -Ofast -Wall -Wextra -ip -xHost normal.c; the conclusion is the same, although gcc generates approximately 10% slower code (for -Ofast as well).
I wouldn't even try to implement an approximate sqrtf: It is already an intrinsic and chances are, your approximation will only be slower...
Having said all these, I don't know the answer to the original question. I thought about it and I also suspect that the there might be another way that doesn't involve the square-root function.
Interesting question in theory; in practice, I doubt that getting rid of that square-root would make any difference in speed in your application.
First, find the angle between your two vectors. From the principle of scalar projection, we know that
|a| * cos(theta) = a . b_hat
. being the dot product operator, |a| being the length of a, theta being the angle between a and b, and b_hat being the normalized form of b.
In your situation, a and b are already unit vectors, so this simplifies to:
cos(theta) = a . b
which we can rearrange to:
theta = acos(a . b)
Lay vectors A and B end to end, and complete the triangle by drawing a line from the start of the first vector to the end of the second. Since two sides are of equal length, we know the triangle is isoceles, so it's easy to determine all of the angles if you already know theta.
That line with length N is the middle vector. We can normalize it if we divide it by N.
From the law of sines, we know that
sin(theta/2)/1 = sin(180-theta)/N
Which we can rearrange to get
N = sin(180-theta) / sin(theta/2)
Note that you'll divide by zero when calculating N if A and B are equal, so it may be useful to check for that corner case before starting.
Summary:
dot_product = a.x * b.x + a.y * b.y + a.z * b.z
theta = acos(dot_product)
N = sin(180-theta) / sin(theta/2)
middle_vector = [(a.x + b.x) / N, (a.y + b.y) / N, (a.z + b.z) / N]
Based on the answers I made some speed comparison.
Edit. with this nieve benchmark, GCC optimizes out the trigonometry yeilding approx the same speeds for both methods, Read #Ali's post for a more complete explanation.
In summery, using re-normalizing is approx 4x faster.
#include <stdio.h>
#include <math.h>
/* gcc mid_v3_v3v3_slerp.c -lm -O3 -o mid_v3_v3v3_slerp_a
* gcc mid_v3_v3v3_slerp.c -lm -O3 -o mid_v3_v3v3_slerp_b -DUSE_NORMALIZE
*
* time ./mid_v3_v3v3_slerp_a
* time ./mid_v3_v3v3_slerp_b
*/
#ifdef USE_NORMALIZE
#warning "Using normalize"
void mid_v3_v3v3_slerp(float v[3], const float v1[3], const float v2[3])
{
float m;
v[0] = (v1[0] + v2[0]);
v[1] = (v1[1] + v2[1]);
v[2] = (v1[2] + v2[2]);
m = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] *= m;
v[1] *= m;
v[2] *= m;
}
#else
#warning "Not using normalize"
void mid_v3_v3v3_slerp(float v[3], const float v1[3], const float v2[3])
{
const float dot_product = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
const float theta = acosf(dot_product);
const float n = 1.0f / (2.0f * cosf(theta * 0.5f));
v[0] = (v1[0] + v2[0]) * n;
v[1] = (v1[1] + v2[1]) * n;
v[2] = (v1[2] + v2[2]) * n;
}
#endif
int main(void)
{
unsigned long long int i = 10000000000;
const float v1[3] = {-0.8659117221832275, 0.4995948076248169, 0.024538060650229454};
const float v2[3] = {0.7000154256820679, 0.7031427621841431, -0.12477479875087738};
float v[3];
while (--i) {
asm (""); /* prevent compiler from optimizing the loop away */
mid_v3_v3v3_slerp(v, v1, v2);
}
printf("done %f %f %f\n", v[0], v[1], v[2]);
return 0;
}

Quadratic functions in c

I have almost everything working except for solving for X in line 25 i keep getting an error saying " term does not evaluate to a function taking 1787 arguments" i had it giving me a 1 or a 0 but as i kept messing with it i lost where i was at and saved over the copy. still new to posting sorry if its hard to read
#include <stdio.h>
#include <math.h>
void quadratic_function()
{
int a,b,c; // variables
long int result; // my X in the quadractic function
long int y,x; // the result
long int quadratic;
printf("enter values for a,b,c\n");
scanf("%i\n %i\n %i", &a,&b,&c);
printf("A=%i B=%i C=%i\n", a,b,c); //Displays Variables
y= pow(b, 2);
result= (y)*-4*(a)*(c); // b^2-4ac
printf("\n%li\n",result);
if (result<0)
printf("Imaginary Number"); // if negative
else (result>0);
x=(-b/2*(a)) +- (sqrt(pow(b, 2)) (-4*(a)*(c))) / (2*(a));
//solving for x
printf("\n %li\n",x);
a = a*x;
b = b*x;
quadratic=pow(a, 2)*(b)*(c); // if positive
//printf("Quadratic equation equal to %li",quadratic); // result
}
int main()
{
quadratic_function();
return 0;
}
The first thing I noticed is that you were trying to do the + and - portions of the quadratic equation at the same time. The equation
x = (-b +- sqrt(b^2 - 4ac)) / 2a
means the same as
x = (-b + sqrt(b^2 - 4ac)) / 2a AND x = (-b - sqrt(b^2 - 4ac)) / 2a
In other words, the equation has two answers if b^2 - 4ac is greater than 0, one answer if it is 0, and no answer if it is negative.
Another thing, the line else (result>0); doesn't really do anything. The rest of the code after that will execute even if you get b^2 - 4ac < 0
Finally, I wasn't entirely sure about your groupings or C++'s precedence with the negative sign, so I changed your parentheses around a bit.
y = pow(b, 2);
result = (y) - (4*a*c); // b^2-4ac
printf("\n%li\n", result);
if (result < 0) {
printf("Imaginary Number"); // if negative
} else if (result == 0) {
x = (-b) / (2 * a); // sqrt(0) = 0, so don't bother calculating it
a = a*x;
b = b*x;
quadratic=pow(a, 2)*(b)*(c);
printf("Quadratic equation equal to %li",quadratic); // result
} else if (result > 0) {
// solve for (-b + sqrt(b^2 - 4ac)) / 2a
x = ((-b) + sqrt(pow(b, 2) - (4 * a * c))) / (2 * a);
printf("\n %li\n",x);
a = a*x;
b = b*x;
quadratic=pow(a, 2)*(b)*(c);
printf("Quadratic equation equal to %li",quadratic); // result
// do it again for (-b - sqrt(b^2 - 4ac)) / 2a
x = ((-b) - sqrt(pow(b, 2) - (4 * a * c))) / (2 * a);
printf("\n %li\n",x);
a = a*x;
b = b*x;
quadratic=pow(a, 2)*(b)*(c);
printf("Quadratic equation equal to %li",quadratic);
}

How to determine ring points' orientation correctly?

Based on How to determine if a list of polygon points are in clockwise order?
I've come up with the following code:
bool PointsClockwise(const std::vector<MyPoint>& points)
{
double sum = 0.0;
for(size_t i = 0; i < points.size() - 1; ++i)
sum += (points[i+1].x()-points[i].x()) * (points[i+1].y()+points[i].y());
return sum > 0.0;
}
However, this seems to have wrong result in certain cases. Take for example the following ring:
LINESTRING(0 119,0 60,694 70,704 72,712 77,719 83,723 92,725 102,723 111,719 120,712 126,703 130)
It is in counter-clockwise order, but the function returns true.
Thanks!
You missed one of the line segments from your summation - namely the one connecting the last point with the first.
Try that:
bool PointsClockwise(const std::vector<MyPoint>& points)
{
double sum = 0.0;
for(size_t i = 0; i < points.size() - 1; ++i)
sum += (points[i+1].x()-points[i].x()) * (points[i+1].y()+points[i].y());
sum += (points[0].x()-points[points.size()-1].x()) * (points[0].y()+points[points.size()-1].y());
return sum > 0.0;
}
You need to include the case i == points.size() - 1, but to do that, you need to do some modular arithmetic in the loop, or else separate out the last iteration. Actually, just initialize sum to the last iteration:
double sum = (points[0].x() - points[points.size() - 1].x())
* (points[0].y() + points[points.size() - 1].y());
and end the iteration at i < points.size() - 1

Interpolating values between interval, interpolation as per Bezier curve

To implement a 2D animation I am looking for interpolating values between two key frames with the velocity of change defined by a Bezier curve. The problem is Bezier curve is represented in parametric form whereas requirement is to be able to evaluate the value for a particular time.
To elaborate, lets say the value of 10 and 40 is to be interpolated across 4 seconds with the value changing not constantly but as defined by a bezier curve represented as 0,0 0.2,0.3 0.5,0.5 1,1.
Now if I am drawing at 24 frames per second, I need to evaluate the value for every frame. How can I do this ? I looked at De Casteljau algorithm and thought that dividing the curve into 24*4 pieces for 4 seconds would solve my problem but that sounds erroneous as time is along the "x" axis and not along the curve.
To further simplify
If I draw the curve in a plane, the x axis represents the time and the y axis the value I am looking for. What I actually require is to to be able to find out "y" corresponding to "x". Then I can divide x in 24 divisions and know the value for each frame
I was facing the same problem: Every animation package out there seems to use Bézier curves to control values over time, but there is no information out there on how to implement a Bézier curve as a y(x) function. So here is what I came up with.
A standard cubic Bézier curve in 2D space can be defined by the four points P0=(x0, y0) .. P3=(x3, y3).
P0 and P3 are the end points of the curve, while P1 and P2 are the handles affecting its shape. Using a parameter t ϵ [0, 1], the x and y coordinates for any given point along the curve can then be determined using the equations
A) x = (1-t)3x0 + 3t(1-t)2x1 + 3t2(1-t)x2 + t3x3 and
B) y = (1-t)3y0 + 3t(1-t)2y1 + 3t2(1-t)y2 + t3y3.
What we want is a function y(x) that, given an x coordinate, will return the corresponding y coordinate of the curve. For this to work, the curve must move monotonically from left to right, so that it doesn't occupy the same x coordinate more than once on different y positions. The easiest way to ensure this is to restrict the input points so that x0 < x3 and x1, x2 ϵ [x0, x3]. In other words, P0 must be to the left of P3 with the two handles between them.
In order to calculate y for a given x, we must first determine t from x. Getting y from t is then a simple matter of applying t to equation B.
I see two ways of determining t for a given y.
First, you might try a binary search for t. Start with a lower bound of 0 and an upper bound of 1 and calculate x for these values for t via equation A. Keep bisecting the interval until you get a reasonably close approximation. While this should work fine, it will neither be particularly fast nor very precise (at least not both at once).
The second approach is to actually solve equation A for t. That's a bit tough to implement because the equation is cubic. On the other hand, calculation becomes really fast and yields precise results.
Equation A can be rewritten as
(-x0+3x1-3x2+x3)t3 + (3x0-6x1+3x2)t2 + (-3x0+3x1)t + (x0-x) = 0.
Inserting your actual values for x0..x3, we get a cubic equation of the form at3 + bt2 + c*t + d = 0 for which we know there is only one solution within [0, 1]. We can now solve this equation using an algorithm like the one posted in this Stack Overflow answer.
The following is a little C# class demonstrating this approach. It should be simple enough to convert it to a language of your choice.
using System;
public class Point {
public Point(double x, double y) {
X = x;
Y = y;
}
public double X { get; private set; }
public double Y { get; private set; }
}
public class BezierCurve {
public BezierCurve(Point p0, Point p1, Point p2, Point p3) {
P0 = p0;
P1 = p1;
P2 = p2;
P3 = p3;
}
public Point P0 { get; private set; }
public Point P1 { get; private set; }
public Point P2 { get; private set; }
public Point P3 { get; private set; }
public double? GetY(double x) {
// Determine t
double t;
if (x == P0.X) {
// Handle corner cases explicitly to prevent rounding errors
t = 0;
} else if (x == P3.X) {
t = 1;
} else {
// Calculate t
double a = -P0.X + 3 * P1.X - 3 * P2.X + P3.X;
double b = 3 * P0.X - 6 * P1.X + 3 * P2.X;
double c = -3 * P0.X + 3 * P1.X;
double d = P0.X - x;
double? tTemp = SolveCubic(a, b, c, d);
if (tTemp == null) return null;
t = tTemp.Value;
}
// Calculate y from t
return Cubed(1 - t) * P0.Y
+ 3 * t * Squared(1 - t) * P1.Y
+ 3 * Squared(t) * (1 - t) * P2.Y
+ Cubed(t) * P3.Y;
}
// Solves the equation ax³+bx²+cx+d = 0 for x ϵ ℝ
// and returns the first result in [0, 1] or null.
private static double? SolveCubic(double a, double b, double c, double d) {
if (a == 0) return SolveQuadratic(b, c, d);
if (d == 0) return 0;
b /= a;
c /= a;
d /= a;
double q = (3.0 * c - Squared(b)) / 9.0;
double r = (-27.0 * d + b * (9.0 * c - 2.0 * Squared(b))) / 54.0;
double disc = Cubed(q) + Squared(r);
double term1 = b / 3.0;
if (disc > 0) {
double s = r + Math.Sqrt(disc);
s = (s < 0) ? -CubicRoot(-s) : CubicRoot(s);
double t = r - Math.Sqrt(disc);
t = (t < 0) ? -CubicRoot(-t) : CubicRoot(t);
double result = -term1 + s + t;
if (result >= 0 && result <= 1) return result;
} else if (disc == 0) {
double r13 = (r < 0) ? -CubicRoot(-r) : CubicRoot(r);
double result = -term1 + 2.0 * r13;
if (result >= 0 && result <= 1) return result;
result = -(r13 + term1);
if (result >= 0 && result <= 1) return result;
} else {
q = -q;
double dum1 = q * q * q;
dum1 = Math.Acos(r / Math.Sqrt(dum1));
double r13 = 2.0 * Math.Sqrt(q);
double result = -term1 + r13 * Math.Cos(dum1 / 3.0);
if (result >= 0 && result <= 1) return result;
result = -term1 + r13 * Math.Cos((dum1 + 2.0 * Math.PI) / 3.0);
if (result >= 0 && result <= 1) return result;
result = -term1 + r13 * Math.Cos((dum1 + 4.0 * Math.PI) / 3.0);
if (result >= 0 && result <= 1) return result;
}
return null;
}
// Solves the equation ax² + bx + c = 0 for x ϵ ℝ
// and returns the first result in [0, 1] or null.
private static double? SolveQuadratic(double a, double b, double c) {
double result = (-b + Math.Sqrt(Squared(b) - 4 * a * c)) / (2 * a);
if (result >= 0 && result <= 1) return result;
result = (-b - Math.Sqrt(Squared(b) - 4 * a * c)) / (2 * a);
if (result >= 0 && result <= 1) return result;
return null;
}
private static double Squared(double f) { return f * f; }
private static double Cubed(double f) { return f * f * f; }
private static double CubicRoot(double f) { return Math.Pow(f, 1.0 / 3.0); }
}
You have a few options:
Let's say your curve function F(t) takes a parameter t that ranges from 0 to 1 where F(0) is the beginning of the curve and F(1) is the end of the curve.
You could animate motion along the curve by incrementing t at a constant change per unit of time.
So t is defined by function T(time) = Constant*time
For example, if your frame is 1/24th of a second, and you want to move along the curve at a rate of 0.1 units of t per second, then each frame you increment t by 0.1 (t/s) * 1/24 (sec/frame).
A drawback here is that your actual speed or distance traveled per unit time will not be constant. It will depends on the positions of your control points.
If you want to scale speed along the curve uniformly you can modify the constant change in t per unit time. However, if you want speeds to vary dramatically you will find it difficult to control the shape of the curve. If you want the velocity at one endpoint to be much larger, you must move the control point further away, which in turn pulls the shape of the curve towards that point. If this is a problem, you may consider using a non constant function for t. There are a variety of approaches with different trade-offs, and we need to know more details about your problem to suggest a solution. For example, in the past I have allowed users to define the speed at each keyframe and used a lookup table to translate from time to parameter t such that there is a linear change in speed between keyframe speeds (it's complicated).
Another common hangup: If you are animating by connecting several Bezier curves, and you want the velocity to be continuous when moving between curves, then you will need to constrain your control points so they are symmetrical with the adjacent curve. Catmull-Rom splines are a common approach.
I've answered a similar question here. Basically if you know the control points before hand then you can transform the f(t) function into a y(x) function. To not have to do it all by hand you can use services like Wolfram Alpha to help you with the math.

Resources