OpenGL how to create a sphere from half-sphere in c++ - c++

So, from a material I have, I managed to somehow complete it to half-sphere, the original destination. But now I have to make a sphere from the said half-sphere and I'm lost. I haven't met an answer online that has a fourth parameter (raze). Can someone tell me what I'm missing?
The code:
void drawSphere(double r, int lats, int longs, double raze) {
double alpha = acos((r - raze)/r);
bool ind = true;
int i, j;
for(i = 0; i <= lats; i++) {
double lat0 = M_PI * (-0.5 + (double) (i - 1) / lats);
double z0 = sin(lat0);
double zr0 = cos(lat0);
double lat1 = M_PI * (-0.5 + (double) i / lats);
double z1 = sin(lat1);
double zr1 = cos(lat1);
if (lat0>alpha && lat1>alpha){
if (ind){
ind = false;
double z0 = sin(alpha);
double zr0 = cos(alpha);
double lat1 = M_PI * (-0.5 + (double) (i-1) / lats);
double z1 = sin(lat1);
double zr1 = cos(lat1);
glBegin(GL_QUAD_STRIP);
for(j = 0; j <= longs; j++) {
double lng = 2 * M_PI * (double) (j - 1) / longs;
double x = cos(lng);
double y = sin(lng);
glColor3f(1, 0, 0);
//glNormal3f(x * zr0, y * zr0, z0);
glVertex3f(r * x * zr0, r * y * zr0, r * z0);
//glNormal3f(x * zr1, y * zr1, z1);
glVertex3f(r * x * zr1, r * y * zr1, r * z1);
}
glEnd();
}
glBegin(GL_QUAD_STRIP);
for(j = 0; j <= longs; j++) {
double lng = 2 * M_PI * (double) (j - 1) / longs;
double x = cos(lng);
double y = sin(lng);
glColor3f(1, 0, 0);
//glNormal3f(x * zr0, y * zr0, z0);
glVertex3f(r * x * zr0, r * y * zr0, r * z0);
//glNormal3f(x * zr1, y * zr1, z1);
glVertex3f(r * x * zr1, r * y * zr1, r * z1);
}
glEnd();};
}
}

For a full sphere raze must be equal r. However, the condition if (lat0>alpha && lat1>alpha) is wrong. It has to be:
if (lat0 >= -alpha && lat1 <= alpha)
Note that for a full sphere you need to draw slices from -M_PI/2 to M_PI/2. That means if (lat0 >= -M_PI/2 && lat1 < -M_PI/2).

Related

Problem with ellipse (rotated): incorrect position of any point is detected

When the ellipse is not rotated with this formula 1. If value = 1 - point on the ellipse, if value > 1 - outside, if value < 1 - inside. The program works correctly.
Code:
int checkPointNoAngle(int x0, int y0, int x, int y, int a, int b)
{
int value = (pow((x - x0), 2) / pow(a, 2)) + (pow((y - y0), 2) / pow(b, 2));
return value;
}
I need to work with a rotated ellipse, so I used formula 2.
Now the program incorrectly determines the position of the point.
int checkPoint(int x0, int y0, int x, int y, int a, int b)
{
int angle = 90;
int value = (pow(cos(angle * M_PI / 180)*((x - x0)+sin(angle * M_PI / 180)*(y-y0)), 2) / pow(a, 2)) + (pow(sin(angle * M_PI / 180) * ((x - x0) - cos(angle * M_PI / 180) * (y - y0)), 2) / pow(b, 2));
return value;
}
I drawing an ellipse using this code:
for (int t = 0; t < 360; t++)
{
int x = a * cos(t);
int y = b * sin(t);
int x1 = x * cos(angle * M_PI / 180) + y * sin(angle * M_PI / 180);
int y1 = -x * sin(angle * M_PI / 180) + y * cos(angle * M_PI / 180);
SDL_RenderDrawPoint(ren, x1 + centerX, y1 + centerY);
}
The program draws the ellipse correctly, but determines the position of the point incorrectly.
Examples of work:
3,4,5,6.
Example 4 and 5 works correctly with the checkPointNoAngle method.
I need to rotate the ellipse, so I created checkPoint method.
Example 6 indicates a bug.
The code was confusing a little bit. I tried to simplify the code corresponding to rotation and inverse rotation. The following code seems to work.
#include <iostream>
#include <vector>
#include <cmath>
struct Pt {int x, y;};
double checkPoint(int x0, int y0, int x, int y, int a, int b, int angle) {
double ang = (angle * M_PI)/180;
x = x - x0;
y = y - y0;
double xp = cos(ang)*x + sin(ang)*y;
double yp = -sin(ang)*x + cos(ang)*y;
double value = (xp*xp) / (a*a) + (yp*yp) / (b*b);
return value;
}
std::vector<Pt> gene_ellipse (int centerX, int centerY, int angle, int a, int b) {
std::vector<Pt> v;
double c = cos (angle * M_PI/180);
double s = sin (angle * M_PI/180);
for (int t = 0; t < 360; t++) {
double tt = M_PI * t / 180.0;
double x = a * cos(tt);
double y = b * sin(tt);
int x1 = x * c - y * s;
int y1 = x * s + y * c;
v.push_back (Pt{x1 + centerX, y1 + centerY});
}
return v;
}
int main () {
int centerX = 320;
int centerY = 240;
int angle = 120; // in degrees
int a = 200;
int b = 100;
int index = 25;
auto v = gene_ellipse (centerX, centerY, angle, a, b);
double check = checkPoint (centerX, centerY, v[index].x, v[index].y, a, b, angle);
std::cout << "check = " << check << "\n";
}

How to calculate normal for the cylindrical bevel

I am trying to add bevel to a cylinder , but i am have an issue with calculating the normals for the bevel
the
this is how i am calculating the data for vertices
struct Vertices
{
float x;
float y;
float z;
}
float pieStartAngle = 0.0 * (M_PI / 180.0f);
float angleCircle = 0.0f;
// First fill all the position of vertices
for (int k = 0; k < totalNumberOfPies; k++)
{
for (int i = 0; i < segmentPerPie + 1; i++)
{
Vertices temp;
float initialAngle = pieStartAngle;
angleCircle = (stdvecValuePercent[k] / 100.0f) * totalAngle;
float angle = initialAngle + ((angleCircle *(M_PI / 180)) * i / segmentPerPie);
float x, y, z, tx, ty, tz;
float innerX, innerY, innerZ, innerTx, innerTy;
x = cos(angle) * (radius - bevel);
y = sin(angle) * (radius - bevel);
z = 0.0;
temp.x = x;
temp.y = y;
temp.z = z;
vertices.push_back(temp);
x = cos(angle) * radius;
y = sin(angle) * radius;
z = 0.0 + bevel;
temp.x = x;
temp.y = y;
temp.z = z;
vertices.push_back(temp);
}
pieStartAngle += angleCircle * (M_PI / 180);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
this is how i am calculating the data for normals , i am taking the cross product of three verices to get the vector perpendicular to the face.
for (int i = 0; i < vertices.size(); i++)
{
glm::vec3 vec1 = glm::vec3(vertices[i].x - vertices[i + 1].x, vertices[i].y - vertices[i + 1].y, vertices[i].z - vertices[i + 1].z);
glm::vec3 vec2 = glm::vec3(vertices[i].x - vertices[i + 2].x, vertices[i].y - vertices[i + 2].y, vertices[i].z - vertices[i + 2].z);
glm::vec3 crossProduct = glm::cross(glm::normalize(vec1), glm::normalize(vec2));
crossProduct = glm::normalize(crossProduct);
bevelData.push_back(vertices[i].x);
bevelData.push_back(vertices[i].y);
bevelData.push_back(vertices[i].z);
bevelData.push_back(crossProduct.x );
bevelData.push_back(crossProduct.y );
bevelData.push_back(crossProduct.z);
bevelData.push_back(0.0);
bevelData.push_back(0.0);
}

Mandelbrot Set not displaying at center

I think the problem is how I'm converting the Cartesian coordinate into a Complex number but I have now idea how. Can you please explain how should I convert? Here's what I tried though:
double c_Im = (y + (maxIm - minIm)) / height;
double c_Re = (x + (maxRe - minRe)) / width;
Code:
float minRe = -2.0;
float maxRe = 2.0;
double minIm = -2.0;
double maxIm = 2.0;
for (size_t y = 0; y < height; y++)
{
double c_Im = (y + (maxIm - minIm)) / height;
for (size_t x = 0; x < width; x++)
{
double c_Re = (x + (maxRe - minRe)) / width;
float dx = 0, dy = 0;
int z = 0;
while (dx * dx + dy * dy < 4 && z < maxIterator)
{
float temp = (dx * dx - dy * dy) + c_Re;
dy = 2 * dx * dy + c_Im;
dx = temp;
z++;
}
image.setPixel(x, y, Color(z % 255, z % 255, z % 255));
}
}
not_expected_output.jpg
I think the formula you're looking for is this:
double c_Im = y * (maxIm - minIm) / height + minIm;
double c_Re = x * (maxRe - minRe) / width + minRe;
This is derived from the map formula: Y=(X-A)*(D-C)/(B-A)+C

Visualize un-distorted images received from the Leap motion cameras using OpenCV

I want to use OpenCV to visualize undistorted images, obtained after correction of raw images taken from Leap Motion cameras;
according to the documentation,
https://developer.leapmotion.com/documentation/cpp/devguide/Leap_Images.html
the following code should return corrected images: am I right?
unsigned char destination[320][120];
//define needed variables outside the inner loop
float calibrationX, calibrationY;
float weightX, weightY;
float dX, dX1, dX2, dX3, dX4;
float dY, dY1, dY2, dY3, dY4;
int x1, x2, y1, y2;
int denormalizedX, denormalizedY;
int i, j;
const unsigned char* raw = image.data();
const float* distortion_buffer = image.distortion();
//Local variables for values needed in loop
const int distortionWidth = image.distortionWidth();
const int width = image.width();
const int height = image.height();
for (i = 0; i < destinationWidth; i++) {
for (j = 0; j < destinationHeight; j++) {
//Calculate the position in the calibration map (still with a fractional part)
calibrationX = 63 * i/destinationWidth;
calibrationY = 62 * (1 - j/destinationHeight); // The y origin is at the bottom
//Save the fractional part to use as the weight for interpolation
weightX = calibrationX - truncf(calibrationX);
weightY = calibrationY - truncf(calibrationY);
//Get the x,y coordinates of the closest calibration map points to the target pixel
x1 = calibrationX; //Note truncation to int
y1 = calibrationY;
x2 = x1 + 1;
y2 = y1 + 1;
//Look up the x and y values for the 4 calibration map points around the target
dX1 = distortion_buffer[x1 * 2 + y1 * distortionWidth];
dX2 = distortion_buffer[x2 * 2 + y1 * distortionWidth];
dX3 = distortion_buffer[x1 * 2 + y2 * distortionWidth];
dX4 = distortion_buffer[x2 * 2 + y2 * distortionWidth];
dY1 = distortion_buffer[x1 * 2 + y1 * distortionWidth + 1];
dY2 = distortion_buffer[x2 * 2 + y1 * distortionWidth + 1];
dY3 = distortion_buffer[x1 * 2 + y2 * distortionWidth + 1];
dY4 = distortion_buffer[x2 * 2 + y2 * distortionWidth + 1];
//Bilinear interpolation of the looked-up values:
// X value
dX = dX1 * (1 - weightX) * (1 - weightY) +
dX2 * weightX * (1 - weightY) +
dX3 * (1 - weightX) * weightY +
dX4 * weightX * weightY;
// Y value
dY = dY1 * (1 - weightX) * (1 - weightY) +
dY2 * weightX * (1 - weightY) +
dY3 * (1 - weightX) * weightY +
dY4 * weightX * weightY;
// Reject points outside the range [0..1]
if((dX >= 0) && (dX <= 1) && (dY >= 0) && (dY <= 1)) {
//Denormalize from [0..1] to [0..width] or [0..height]
denormalizedX = dX * width;
denormalizedY = dY * height;
//look up the brightness value for the target pixel
destination[i][j] = raw[denormalizedX + denormalizedY * width];
} else {
destination[i][j] = -1;
}
}
}
Now, I'm using OpenCV to visualize undistorted image:
Mat imgCorrected(120,320,CV_8UC1);
for(int i = 0; i < 120; i++)
for(int j = 0; j < 320; j++)
imgCorrected.at<unsigned char>(i,j) = destination[i][j];
imshow("ImgCorrected", imgCorrected);
And this is the result:
Result
I really don't know what I'm doing wrong.
Thanks for any help.

Rotation of a point about the z-axis

I have 3 vectors in 3D space. Let's call them xaxis, yaxis, and zaxis. These vectors are centered about an arbitrary point somewhere in 3D space. I am interested in rotating the xaxis and yaxis vectors about the zaxis vector a number of degrees θ.
For the following code with values being arbitrary and unimportant:
double xaxis[3], yaxis[3], zaxis[3], point[3], theta;
How would I go about rotating xaxis and yaxis about the zaxis by theta degrees?
Future Note: These attempts do not work. See my answer for the proper solution, which was found with the help of BlueRaja-DannyPflughoeft
My attempt at matrix-based rotation:
double rx[3][3];
double ry[3][3];
double rz[3][3];
double r[3][3];
rx[0][0] = 1;
rx[0][1] = 0;
rx[0][2] = 0;
rx[1][0] = 0;
rx[1][1] = cos(theta);
rx[1][2] = sin(theta);
rx[2][0] = 0;
rx[2][1] = -1.0 * sin(theta);
rx[2][2] = cos(theta);
ry[0][0] = cos(theta);
ry[0][1] = 0;
ry[0][2] = -1.0 * sin(theta);
ry[1][0] = 0;
ry[1][1] = 1;
ry[1][2] = 0;
ry[2][0] = sin(theta);
ry[2][1] = 0;
ry[2][2] = cos(theta);
//No rotation wanted on the zaxis
rz[0][0] = cos(0);
rz[0][1] = sin(0);
rz[0][2] = 0;
rz[1][0] = -1.0 * sin(0);
rz[1][1] = cos(0);
rz[1][2] = 0;
rz[2][0] = 0;
rz[2][1] = 0;
rz[2][2] = 1;
vtkMath::Multiply3x3(rx, ry, r); //Multiplies rx by ry and stores into r
vtkMath::Multiply3x3(r, rz, r); //Multiplies r by rz and stores into r
vtkMath::Multiply3x3(r, xaxis, xaxis);//multiplies a 3x3 by a 3x1
vtkMath::Multiply3x3(r, yaxis, yaxis);//multiplies a 3x3 by a 3x1
This attempt only worked when the plane was in the x-y plane:
double x, y;
x = xaxis[0];
y = xaxis[1];
xaxis[0] = x * cos(theta) - y * sin(theta);
xaxis[1] = x * sin(theta) + y * cos(theta);
x = yaxis[0];
y = yaxis[1];
yaxis[0] = x * cos(theta) - y * sin(theta);
yaxis[1] = x * sin(theta) + y * cos(theta);
Using the axis-angle approach given by BlueRaja-DannyPflughoeft:
double c = cos(theta);
double s = sin(theta);
double C = 1.0 - c;
double Q[3][3];
Q[0][0] = xaxis[0] * xaxis[0] * C + c;
Q[0][1] = xaxis[1] * xaxis[0] * C + xaxis[2] * s;
Q[0][2] = xaxis[2] * xaxis[0] * C - xaxis[1] * s;
Q[1][0] = xaxis[1] * xaxis[0] * C - xaxis[2] * s;
Q[1][1] = xaxis[1] * xaxis[1] * C + c;
Q[1][2] = xaxis[2] * xaxis[1] * C + xaxis[0] * s;
Q[2][0] = xaxis[1] * xaxis[2] * C + xaxis[1] * s;
Q[2][1] = xaxis[2] * xaxis[1] * C - xaxis[0] * s;
Q[2][2] = xaxis[2] * xaxis[2] * C + c;
double x = Q[2][1] - Q[1][2], y = Q[0][2] - Q[2][0], z = Q[1][0] - Q[0][1];
double r = sqrt(x * x + y * y + z * z);
//xaxis[0] /= r;
//xaxis[1] /= r;
//xaxis[2] /= r;
xaxis[0] = x;// ?
xaxis[1] = y;
xaxis[2] = z;
Thanks to BlueRaja - Danny Pflughoeft:
double c = cos(theta);
double s = sin(theta);
double C = 1.0 - c;
double Q[3][3];
Q[0][0] = zaxis[0] * zaxis[0] * C + c;
Q[0][1] = zaxis[1] * zaxis[0] * C + zaxis[2] * s;
Q[0][2] = zaxis[2] * zaxis[0] * C - zaxis[1] * s;
Q[1][0] = zaxis[1] * zaxis[0] * C - zaxis[2] * s;
Q[1][1] = zaxis[1] * zaxis[1] * C + c;
Q[1][2] = zaxis[2] * zaxis[1] * C + zaxis[0] * s;
Q[2][0] = zaxis[0] * zaxis[2] * C + zaxis[1] * s;
Q[2][1] = zaxis[2] * zaxis[1] * C - zaxis[0] * s;
Q[2][2] = zaxis[2] * zaxis[2] * C + c;
xaxis[0] = xaxis[0] * Q[0][0] + xaxis[0] * Q[0][1] + xaxis[0] * Q[0][2];
xaxis[1] = xaxis[1] * Q[1][0] + xaxis[1] * Q[1][1] + xaxis[1] * Q[1][2];
xaxis[2] = xaxis[2] * Q[2][0] + xaxis[2] * Q[2][1] + xaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis
yaxis[0] = yaxis[0] * Q[0][0] + yaxis[0] * Q[0][1] + yaxis[0] * Q[0][2];
yaxis[1] = yaxis[1] * Q[1][0] + yaxis[1] * Q[1][1] + yaxis[1] * Q[1][2];
yaxis[2] = yaxis[2] * Q[2][0] + yaxis[2] * Q[2][1] + yaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis
I see that following matrix multiplication is wrong!
As stated above it can be factored with xaxis[0]
xaxis[0] = xaxis[0] * Q[0][0] + xaxis[0] * Q[0][1] + xaxis[0] * Q[0][2];
xaxis[0] = xaxis[0] * (Q[0][0] + Q[0][1] + Q[0][2]);
This does not look like a matrix multiplication. It should be:
xaxis1[0] = xaxis[0] * Q[0][0] + xaxis[1] * Q[0][1] + xaxis[2] * Q[0][2];
xaxis1[1] = xaxis[0] * Q[1][0] + xaxis[1] * Q[1][1] + xaxis[2] * Q[1][2];
xaxis1[2] = xaxis[0] * Q[2][0] + xaxis[1] * Q[2][1] + xaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis
yaxis1[0] = yaxis[0] * Q[0][0] + yaxis[1] * Q[0][1] + yaxis[2] * Q[0][2];
yaxis1[1] = yaxis[0] * Q[1][0] + yaxis[1] * Q[1][1] + yaxis[2] * Q[1][2];
yaxis1[2] = yaxis[0] * Q[2][0] + yaxis[1] * Q[2][1] + yaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis