C++ equations, not sure if i wrote it correctly - c++

Are and correctly written?
if(x>0.1){z = 2*n+x}
if else(x <= 0.1){x(pow,n) - 1 / sqrt(n(pow,2)) + x(pow,2) * n}
x = n / 2 * n(pow,2) + 3 * n - 2

x is correctly translated to C++.
As for the rest of the code, it would be:
if(x > 0.1) {
z = 2 * n + x;
}
else {
z = pow(x, n) - 1 / sqrt(pow(n, 2) + pow(x, 2) * n);
}

Related

How do I get correct answers using my code with the barycentric formula?

My function getHeightOfTerrain() is calling a barycentric formula function that is not returning the correct height for the one set test height in : heightMapFromArray[][].
I've tried watching OpenGL JAVA Game tutorials 14,21, 22, by "thin matrix" and I am confused on how to use my array: heightMapforBaryCentric in both of the supplied functions, and how to set the arguments that are passed to the baryCentic() function in some sort of manner so that I can solve the problem.
int creaateTerrain(int height, int width)
{
float holderY[6] = { 0.f ,0.f,0.f,0.f,0.f,0.f };
float scaleit = 1.5f;
float holder[6] = { 0.f,0.f,0.f,0.f,0.f,0.f };
for (int z = 0, z2 =0; z < iterationofHeightMap;z2++)
{
//each loop is two iterations and creates one quad (two triangles)
//however because each iteration is by two (i.e. : x=x+2) om bottom
//the amount of triangles is half the x value
//
//number of vertices : 80 x 80 x 6.
//column
for (int x = 0, x2 = 0; x < iterationofHeightMap;x2++)
{
//relevant - A : first triangle - on left triangle
//[row] [colum[]
holder[0] = heightMapFromArray[z][x];
//holder[0] = (float)imageData[(z / 2 * MAP_Z + (x / 2)) * 3];
//holder[0] = holder[0] / 255;// *scaleit;
vertices.push_back(glm::vec3(x, holder[0], z));
//match height map with online barycentric use
heightMapforBaryCentric[x2][z2] = holder[0];
holder[1] = heightMapFromArray[z+2][x];
//holder[1] = (float)imageData[(((z + 2) / 2 * MAP_Z + ((x) / 2))) * 3];
//holder[1] = holder[1] / 255;// 6 * scaleit;
vertices.push_back(glm::vec3(x, holder[1], z + 2));
//match height map with online barycentric use
heightMapforBaryCentric[x2][z2+1] = holder[1];
holder[2] = heightMapFromArray[z+2][x+2];
//holder[2] = (float)imageData[(((z + 2) / 2 * MAP_Z + ((x + 2) / 2))) * 3];
//holder[2] = holder[2] / 255;// *scaleit;
vertices.push_back(glm::vec3(x + 2, holder[2], z + 2));
////match height map with online barycentric use
heightMapforBaryCentric[x2+1][z2+1] = holder[2];
//relevant - B - second triangle (on right side)
holder[3] = heightMapFromArray[z][x];
//holder[3] = (float)imageData[((z / 2)*MAP_Z + (x / 2)) * 3];
//holder[3] = holder[3] / 255;// 256 * scaleit;
vertices.push_back(glm::vec3(x, holder[3], z));
holder[4] = heightMapFromArray[x+2][z+2];
//holder[4] = (float)imageData[(((z + 2) / 2 * MAP_Z + ((x + 2) / 2))) * 3];
//holder[4] = holder[4] / 255;// *scaleit;
vertices.push_back(glm::vec3(x + 2, holder[4], z + 2));
holder[5] = heightMapFromArray[x+2][z];
//holder[5] = (float)imageData[((z / 2)*MAP_Z + ((x + 2) / 2)) * 3];
//holder[5] = holder[5] / 255;// *scaleit;
vertices.push_back(glm::vec3(x + 2, holder[5], z));
x = x + 2;
}
z = z + 2;
}
return(1);
}
float getHeightOfTerrain(float worldX, float worldZ) {
float terrainX = worldX;
float terrainZ = worldZ;
int gridSquareSize = 2.0f;
gridX = (int)floor(terrainX / gridSquareSize);
gridZ = (int)floor(terrainZ / gridSquareSize);
xCoord = ((float)(fmod(terrainX, gridSquareSize)) / (float)gridSquareSize);
zCoord = ((float)(fmod(terrainZ, gridSquareSize)) / (float)gridSquareSize);
if (xCoord <= (1 - zCoord))
{
answer = baryCentric(
//left triangle
glm::vec3(0.0f, heightMapforBaryCentric[gridX][gridZ], 0.0f),
glm::vec3(0.0f, heightMapforBaryCentric[gridX][gridZ+1], 1.0f),
glm::vec3(1.0f, heightMapforBaryCentric[gridX+1][gridZ+1], 1.0f),
glm::vec2(xCoord, zCoord));
// if (answer != 1)
// {
// fprintf(stderr, "Z:gridx: %d gridz: %d answer: %f\n", gridX, gridZ,answer);
//
// }
}
else
{
//right triangle
answer = baryCentric(glm::vec3(0, heightMapforBaryCentric[gridX][gridZ], 0),
glm::vec3(1,heightMapforBaryCentric[gridX+1][gridZ+1], 1),
glm::vec3(1,heightMapforBaryCentric[gridX+1][gridZ], 0),
glm::vec2(xCoord, zCoord));
}
if (answer == 1)
{
answer = 0;
}
//answer = abs(answer - 1);
return(answer);
}
float baryCentric(glm::vec3 p1, glm::vec3 p2, glm::vec3 p3 , glm::vec2 pos) {
float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z);
float l1 = ((p2.z - p3.z) * (pos.x - p3.x) + (p3.x - p2.x) * (pos.y - p3.z)) / det;
float l2 = ((p3.z - p1.z) * (pos.x - p3.x) + (p1.x - p3.x) * (pos.y - p3.z)) / det;
float l3 = 1.0f - l1 - l2;
return (l1 * p1.y + l2 * p2.y + l3 * p3.y);
}
My expected results were that the center of the test grid's height to be the set value .5 and gradually less as the heights declined. My results were the heights being all the same, varied, or increasing. Usually these heights were under the value of one.

Sum of increasing alternate terms in python

I need to evaluate the finite sum of numbers which are increasing in absolute value, but are alternate. Problem is: the abolute values grow too fast and it starts accumulating numerical errors. These the functions definitions, one (Gj_full) straight to it and the other (Gj) recursively. fact_quo is a simple factorial function.
def fact_quo(n, m=1):
if (type(n) != int) or (type(m) != int):
raise TypeError("Arguments must be integers.")
if (n < 0) or (m < 0):
raise ValueError("n=" + str(n) + "\t m=" + str(m))
if (n == 0) or (n == 1) or (n == m):
return 1
if (n < m):
raise ValueError("n=" + str(n) + "\t m=" + str(m))
f = n
while n > (m+1):
n -= 1
f *= n
return f
def Gj_full(X, Y, Xl, Yl, j=0, coef=1):
if (X - Y + Xl + Yl) % 2 or X < Y or Y < j:
raise ValueError
u = (X - Y + Xl + Yl) // 2
v = coef * (2 ** (X - Y) * fact_quo(X, Y-j) * fact_quo(u+j, j) *
4 ** j * (-1) ** j)
w = 3 ** (u+j) * fact_quo(X-Y+j)
den2 = fact_quo(X) * fact_quo(Xl) * fact_quo(Yl)
z = (np.sqrt(fact_quo(X)) * np.sqrt(fact_quo(Y))
* np.sqrt(fact_quo(Xl)) * np.sqrt(fact_quo(Yl)))
return (v / (den2 * w)) * z
def Gj(X, Y, Xl, Yl, j=0, coef=1):
if (X - Y + Xl + Yl) % 2 or X < Y or Y < j:
raise ValueError
kX, kY, kXl, kYl, kj = X % 2, Y % 2, Xl % 2, Yl % 2, 0
g = coef * Gj_full(kX, kY, kXl, kYl, kj)
while kX < X:
u = (kX - kY + kXl + kYl) // 2
v = 4 * (u + kj + 1)
w = 3 * (kX + 2 - kY + kj) * (kX + 1 - kY + kj)
g *= (v / w) * np.sqrt(kX + 2) * np.sqrt(kX + 1)
kX += 2
while kXl < Xl:
u = (kX - kY + kXl + kYl) // 2
v = u + kj + 1
w = 3 * (kXl + 2) * (kXl + 1)
g *= (v / w) * np.sqrt(kXl + 2) * np.sqrt(kXl + 1)
kXl += 2
while kYl < Yl:
u = (kX - kY + kXl + kYl) // 2
v = u + kj + 1
w = 3 * (kYl + 2) * (kYl + 1)
g *= (v / w) * np.sqrt(kYl + 2) * np.sqrt(kYl + 1)
kYl += 2
while kY < Y:
u = (kX - kY + kXl + kYl) // 2
v = 3 * (kX - kY + kj) * (kX - kY - 1 + kj)
w = 4 * (kY + 2 - kj) * (kY + 1 - kj) * (u + kj)
g *= (v / w) * np.sqrt(kY + 2) * np.sqrt(kY + 1)
kY += 2
while kj < j:
u = (kX - kY + kXl + kYl) // 2
v = -4 * (kY - kj) * (u + kj + 1)
w = 3 * (kX - kY + kj + 1) * (kj + 1)
g *= (v / w)
kj += 1
return g
The (4/3) ** j and the factorials quicly increase the absolute value of the summing terms. The sum, however, are supposed to be smaller than 1. In fact, for X = Y and Xl = Yl = 0, the sum equals to (-1/3) ** X.
The precision for infinitely large numbers for floats are not available yet without using a lib. Therefore you should look into the decimal lib, you can even set the precision. Eg.
import decimal
decimal.getcontext().prec = 100
def pi():
pi = decimal.Decimal(0)
for k in range(350):
pi += (decimal.Decimal(4)/(decimal.Decimal(8)*decimal.Decimal(k+1))...)
If you manage to force all the numbers to be integers, you don't need to worry about it

C++ seg fault on gaussian mean filter using cimg

I just tried implemting this filter using cimg but keep getting a seg fault. I am not sure why this is happening as the other filters that I have been using do not have that issue. Is there anything obvious that I am missing here?
CImg<float> gaussianBlur(CImg<float> source)
{
double frame[25];
double mean = 0;
int width = source.width;
int height = source.height;
CImg<float> destination;
destination = source;
for (int x = 1; x < int(width) - 3; x++)
{
for (int y = 1; y < int(height) - 3; y++)
{
mean = 0.0;
frame[0] = int(source(x - 2 ,y - 2)) * .003765;
frame[1] = int(source(x - 1 ,y - 2)) * .015019;
frame[2] = int(source(x - 0 ,y - 2)) * .023792;
frame[3] = int(source(x + 1 ,y - 2)) * .015019;
frame[4] = int(source(x + 2 ,y - 2)) * .003765;
frame[5] = int(source(x - 2 ,y - 1)) * .015019;
frame[6] = int(source(x - 1 ,y - 1)) * .059912;
frame[7] = int(source(x - 0 ,y - 1)) * .094907;
frame[8] = int(source(x + 1 ,y - 1)) * .059912;
frame[9] = int(source(x + 2 ,y - 1)) * .015019;
frame[10] = int(source(x - 2 ,y - 0)) * .023792;
frame[11] = int(source(x - 1 ,y - 0)) * .094907;
frame[12] = int(source(x - 0 ,y - 0)) * .150342;
frame[13] = int(source(x + 1 ,y - 0)) * .094907;
frame[14] = int(source(x + 2 ,y - 0)) * .023792;
frame[15] = int(source(x - 2 ,y + 1)) * .015019;
frame[16] = int(source(x - 1 ,y + 1)) * .059912;
frame[17] = int(source(x - 0 ,y + 1)) * .094907;
frame[18] = int(source(x + 1 ,y + 1)) * .059912;
frame[19] = int(source(x + 2 ,y + 1)) * .015019;
frame[20] = int(source(x - 2 ,y + 2)) * .003765;
frame[21] = int(source(x - 1 ,y + 2)) * .015019;
frame[22] = int(source(x - 0 ,y + 2)) * .023792;
frame[23] = int(source(x + 1 ,y + 2)) * .015019;
frame[24] = int(source(x + 2 ,y + 2)) * .003765;
for (int z = 0; z < 25; z++)
{
mean += frame[z];
}
destination(x,y) = float(mean / 25);
}
}
return destination;
}
for (int y = 1; y < int(height) - 3; y++)
{
mean = 0.0;
frame[0] = int(source(x - 2 ,y - 2)) * .003765;
When y == 1 you have y - 2 == -1, so you have an out-of-bounds access to the source image.

how can i change the b-spline curves from 4 point to 6?

I have a code on C++ it's b-spline curve that has 4 points if I want to change it to 6 point what shall I change in the code?
You can check the code:
#include "graphics.h"
#include <math.h>
int main(void) {
int gd, gm, page = 0;
gd = VGA;
gm = VGAMED;
initgraph(&gd, &gm, "");
point2d pontok[4] = { 100, 100, 150, 200, 170, 130, 240, 270 }; //pontok means points
int ap;
for (;;) {
setactivepage(page);
cleardevice();
for (int i = 0; i < 4; i++)
circle(integer(pontok[i].x), integer(pontok[i].y), 3);
double t = 0;
moveto((1.0 / 6) * (pontok[0].x * pow(1 - t, 3) +
pontok[1].x * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].x * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].x * t * t * t),
(1.0 / 6) * (pontok[0].y * pow(1 - t, 3) +
pontok[1].y * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].y * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].y * t * t * t));
for (t = 0; t <= 1; t += 0.01)
lineto(
(1.0 / 6) * (pontok[0].x * pow(1 - t, 3) +
pontok[1].x * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].x * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].x * t * t * t),
(1.0 / 6) * (pontok[0].y * pow(1 - t, 3) +
pontok[1].y * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].y * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].y * t * t * t));
/* Egerkezeles */ //Egerkezeles means mouse event handling
if (!balgomb)
ap = getactivepoint((point2d *)pontok, 4, 5);
if (ap >= 0 && balgomb) { //balgomb means left mouse button
pontok[ap].x = egerx; //eger means mouse
pontok[ap].y = egery;
}
/* Egerkezeles vege */
setvisualpage(page);
page = 1 - page;
if (kbhit())
break;
}
getch();
closegraph();
return 0;
}
From your formula, it looks like you are trying to draw a cubic Bezier curve. But the formula does not seem entirely correct. You can google "cubic Bezier curve" to find the correct formula. The Wikipedia page contains the formula for any degree of Bezier curve. You can find the "6-points" formula from there by using degree = 5.

Why do these RNG's in C++ and R not produce similar results?

Please excuse the disgustingly noobish nature of this post, but I have a question for those who program in C++ and R on their personal computer.
Question: Why are these random numbers produced from the two programs below not equal, and how do I resolve this issue?
Firstly, I suspect that I have misused the local function and the <<- operator in the R program.
Secondly, I suspect it may be a floating-accuracy issue. It's not immediately obvious to me how the two programs are different, so I don't know how to go about this problem.
I have tried casting all my calculations in C++ to double/float (even long double), and using fmod instead of the modulus operator %: different outputs again, but still not similar to the output in R. I do not know if it of any significant importance, but I want to add that I am compiling the C++ code using the G++ compiler.
Algorithm: The following algorithm can be used in any standard personal computer. It was proposed to use in parallel three word generators,
mk = 171 mk-1 (mod 30269)
m'k = 172 m'k-1 (mod 30307)
m''k = 172 m''k-1 (mod 30323)
and to use as pseudorandom numbers the fractional parts
gk = {mk / 30269 + m'k / 30307 + m''k / 30323}
I have used the initial values m0 = 5, m'0 = 11, and m''0 = 17.
Programs: I have the following program in C++:
//: MC:Uniform.cpp
// Generate pseudo random numbers uniformly between 0 and 1
#include <iostream>
#include <math.h> // For using "fmod()"
using namespace std;
float uniform(){
// A sequence of initial values
static int x = 5;
static int y = 11;
static int z = 17;
// Some integer arithmetic required
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (x % 176) - 35 * (y / 176);
z = 170 * (x % 178) - 63 * (z / 178);
/* If both operands are nonnegative then the
remainder is nonnegative; if not, the sign of
the remainder is implementation-defined. */
if(x < 0)
x = x + 30269;
if(y < 0)
y = y + 30307;
if(z < 0)
z = z + 30323;
return fmod(x / 30269. + y / 30307. + z / 30323., 1.);
}
int main(){
// Print 5 random numbers
for(int i = 0; i < 5; i++){
cout << uniform() << ", ";
}
}///:~
The program exites with code and outputs the following:
0.686912, 0.329174, 0.689649, 0.753722, 0.209394,
I also have a program in R, that looks like the following:
## Generate pseudo random numbers uniformly between 0 and 1
uniform <- local({
# A sequence of initial values
x = 5
y = 11
z = 17
# Use the <<- operator to make x, y and z local static
# variables in R.
f <- function(){
x <<- 171 * (x %% 177) - 2 * (x / 177)
y <<- 172 * (y %% 176) - 35 * (y / 176)
z <<- 170 * (z %% 178) - 63 * (z / 178)
return((x / 30269. + y / 30307. + z / 30323.)%%1.)
}
})
# Print 5 random numbers
for(i in 1:5){
print(uniform())
}
This program exites with code as well and produces the output
[1] 0.1857093
[1] 0.7222047
[1] 0.05103441
[1] 0.7375034
[1] 0.2065817
Any suggestions are appreciated, thanks in advance.
You need a few more %/%'s (integer division) in your R code. Remember that numeric variables in R are floating-point, not integer, by default; so / will do ordinary division with a non-integral quotient. You've also left out the part where you deal with negative x/y/z.
f <- function(){
x <<- 171 * (x %% 177) - 2 * (x %/% 177)
y <<- 172 * (y %% 176) - 35 * (y %/% 176)
z <<- 170 * (z %% 178) - 63 * (z %/% 178)
if(x < 0)
x <<- x + 30269;
if(y < 0)
y <<- y + 30307;
if(z < 0)
z <<- z + 30323;
return((x / 30269. + y / 30307. + z / 30323.)%%1)
}
After making those changes, there doesn't seem to be anything seriously wrong with the result. A quick histogram of 100000 random draws looks very uniform, and there's no autocorrelation I can find. Still doesn't match your C++ result though....
There's a simple copy/paste error in your C++ code. This
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (x % 176) - 35 * (y / 176);
z = 170 * (x % 178) - 63 * (z / 178);
should be this.
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (y % 176) - 35 * (y / 176);
z = 170 * (z % 178) - 63 * (z / 178);