C++ Advanced 3D coordinates to 2D Coordinates - c++

My question: How to convert a 3D coordinate on a 2D screen?
I red a lot about that but all my research just showed half answered or even unanswered replies, some were wrong (tested them) so I ask again and try to add as much detail as possible.
Here are the structures we will work with:
struct COORD3D
{
int X;
int Y;
int Z;
};
struct PAN3D//Rotate around these axis
{
float X;
float Y;
float Z;
};
struct COLOR
{
Uint8 R;//RED
Uint8 G;//GREEN
Uint8 B;//BLUE
Uint8 A;//ALPHA
};
struct CAMERA
{
COORD3D Pos;
PAN3D Rot;
float angle;
int RESX;//X Resolution
int RESY;//Y Resolution
};
struct POI
{
COORD3D Pos;
COLOR Col;
};
struct OBJECT
{
COORD3D Pos;//absolute position
list<POI> dots;//relative to object position
list<pair<POI*, POI*>> lines;//Pointers to the dots to connect them
PAN3D Rot;//absolute rotation
};
Now what I need is a function that looks like:
POI Convert3dTo2d(CAMERA cam, POI point);
(must be a "POI" because of the color ;) )
I already got an alogythm that goes through all objects and all of their points
And the fact that there is a camera tells you that it's not an orthograhic voew but a perspective.
Please comment the code you write here ropperly so everyone can understand it.
If you got no clue of how to do this or just got approaches or non direct solutions, please don't answer, that doesn't really help us.
http://sta.sh/0de60ynp9id <- This image should describe it a bit
Os (Windows 7), Microsoft Visual Studio 2013(I'm just using the c++ part of it)
I Build it for x64 (if it is important ;) )
But I don't think that is important for a little bit mathematic algorythms
If you got any questions, feel free to ask me
Okay, I think I got a new( to me new) way to do this, gonna try it tomorrow and will tell you if it work's (that's the part that everyone forgets but I try not to forget it)

You need to multiply your point by a view and projection matrix.
A view matrix translates the point into camera space. Aka, relative to CAMERA.
A projection matrix transforms the point from 3D space into a projection space. You'll need to decide what sort of projection you want. For example, orthographic projection or perspective projection.
See the matrix at the bottom of these pages for the layout of these matrices.
LookAtLH, or the view matrix:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb281710(v=vs.85).aspx
OrthoLH, or the projection matrix using orthographic projection:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb281723(v=vs.85).aspx
You'll also need to look into how to perform matrix multiplication.

The only way I can interpret this question is that you want to project a 3d point(s) onto a 2d plane. If that's not what you're looking for, clarify your question. If that is what you want, countless resources for 3d projection are around: http://en.wikipedia.org/wiki/3D_projection
You will need to multiply your points by a projection matrices to project(or "convert"?) your points on a 2d plane.

I suggest you can look at the following links for an explanation of transform 3D coordinates to 2D coordinates,
The OpenGL transform pipeline
OpenGL transform

Related

Is it logical wanting to combine CGAL with Quaternions

I am creating a Discrete Element Method simulation program and I am using CGAL to describe the polyhedrons. From reading literature I was planning to do my differential equations for rotation with Quaternions due to the better numerical stability and lack of gimbal lock. However CGAL does not seem to support rotation based on quaternions. (Please tell me if I am incorrect here) I find it a bit surprising that this seems to be missing, certainly since CGAL likes to be absolute in its accuracy which seems to fit well with the numerical stability of quaternions.
Question: Can I somehow combine Boost Quaternions with CGAL or is there any easy way to implement this. And if so, would this be a logical idea to try?
The other options I think I have are:
writing my differential equations for the affine rotation used is CGAL and deal with the downsides there.
store the orientation as an affine rotation matrix and convert it to Quaternions and use this in the diff. equations. Obviously I am worried about the needed conversion step here every timestep.
Any suggestions or other options that I might think of are greatly appreciated.
First Option: Use the Aff_transformation_3 class
CGAL does not provide a quaternion class, it does provide the Aff_transformation_3 class though. Which you could easily use like this:
CGAL::Surface_mesh<Kernel> P;
std::transform( P.points_begin(), P.points_end(), P.points_begin(), yourAffineTransformation);
for defining the transformation matrix see this.
Second Option: Use Quaternions
If you want to use quaternions you would need to construct one with an external library. For example you could use Eigen:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> //or whichever kernel suits your needs
#include <CGAL/Surface_mesh.h>
#include <Eigen/Geometry>
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Polyhedron = CGAL::Surface_mesh<Kernel>;
using Point = CGAL::Point_3<Kernel>;
// define the function that rotates your mesh
template <typename Vect, typename Quaternion>
void rotateCGALPolyhedron(Polyhedron P, Vect to_rotation_center,
Quaternion quat) {
for (auto vi : P.vertices()) {
Point p = P.point(vi);
// translate your point to the rotation center. In your case this would be
// the center of mass of the Polyhderon
Vect V(p[0] - to_rotation_center[0], p[1] - to_rotation_center[1],
p[2] - to_rotation_center[2]);
// construct the translation vector that moves your point to the rotated
// position
Vect v = quat * V; //the Vect operator*(Quaternion, Vect) must be implemented!! If you use Eigen::Quaternion you could use Eigen::Vector3d
// retranslate the point back to its initial position and translate it using
// the previously created translation vector
P.point(size_t(vi)) =
Point(to_rotation_center[0] + v[0], to_rotation_center[1] + v[1],
to_rotation_center[2] + v[2]);
}
}
int main() {
// define your rotation using eigen's quaternion class
Eigen::Quaternion<double> quad(..);
Eigen::Vector_3d centerOfMass; //find the center of mass of the mesh you want to rotate
rotateCGALPolyhedron(P.vertices.begin(), P.vertices.end(), centerOfMass,
quad);
return 0;
}
As you can see since cgal does not have an implementation for quaternions if you want to use quaternions the code is lengthy compared to the Aff_transformation_3 case.

How do I correctly compute this final uniform matrix?

Im trying to understand how matrix transformations work in opengl/glsl, and Im wondering how to make a single 4x4 id-matrix that has the potential for every scale/rotation/translation.
So, after all the binding and whatnot, im only uniform/inputting 1 matrix to designate its location/spin.
This idea seems correct to me, but I cant figure out how to make the object move without distorting it. It rotates just fine, and it scales as well.
But idk how to apply the translation to the id matrix, if that makes sense. In any case, this is my relevant code:
//update matrix
glUniformMatrix4fv(transform, 1, GL_FALSE, glm::value_ptr(ident));
//spin according to z
void object::spinz(float a) { ident = glm::rotate(ident, a, glm::vec3(0.0f, 0.0f, 1.0f)); }
this will modify my
glm::mat4 ident();//id matrix
but when i try giving it translation:
void object::translate(float x, float y, float z);
the method itself will only distort the object/matrix/result
ident += glm::vec4(x, y, z, 0);
what am I doing wrong? Should I even try to only have 1 uniform input?
Solution: the idea for translation is just wrong. A correct one would look more like this: (but the main thing is doing it seperately for each object)
glm::mat4 test = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, z));
finaluniformmatrix *= test;
Or basically make a unique translation matrix, that I then multiply with the overall projection*view matrix.
edit: a cheaper translation is:
matrix[3][0]=x;matrix[3][1]=y;matrix[3][2]=z; //where xyz are xyz coordinates.
ps: why am I getting downvotes for this? This is me finding out (some time ago) that you need a unique identity matrix for rendering seperate objects, and not just the same matrix for everything. (like mixing up projection, view, identity, by adding them for each object)
You can use a number of individual matrix operations, and multiply them together to turn them in to a single matrix that specifies the entire operation. Any number of 4x4 matrices can be multiplied and the order IS important.
Also be wary of non uniform scale and rotation, which can sometimes have the effect of "sheering" the object.
You can fairly simply build translation, rotation-x, rotation-y, rotation-z and scale 4x4 matrices and multiply them together to create a single matrix.
http://www.flipcode.com/documents/matrfaq.html#Q11
http://www.flipcode.com/documents/matrfaq.html#Q41
I'm not sure about the code you are using tho - I'd suggest only using 4x4 matrix and multiply operations to begin with and work from there.

Normals probably not consistent after CGAL 3D Surface Mesh Generation

I use the package from CGAL, 3D Surface Mesh Generation.
http://doc.cgal.org/latest/Surface_mesher/index.html#Chapter_3D_Surface_Mesh_Generation
I started from the example code:
http://doc.cgal.org/latest/Surface_mesher/Surface_mesher_2mesh_an_implicit_function_8cpp-example.html
and now tried to extract the relevant facets (=triangles) to display from the variable c2t3 of type C2t3. A good explanation how to do that was in
http://wiki.schmid.dk/wiki/index.php/CGAL
I followed this explanation with a little modification, that I found in
http://cgal-discuss.949826.n4.nabble.com/normal-vector-of-a-facet-td1580004.html
Now when I give the triangles to OpenGL by the code-snippet below, the displayed surface is a mosaic of yellow (my lighting color) and black triangles - I conclude this is because the surface normals are not consistent. But how can that be? If one follows the argument in the last link above it should come out right. Could anyone with better acquaintance with CGAL and the 3D Surface Mesh Generation and its data structures give me some guidance? (I also tried several obvious alternatives to the code below, but nothing worked correctly).
for (C2t3::Facet_iterator fit = c2t3.facets_begin(); fit != c2t3.facets_end(); ++fit) {
const Point_3& p0 = fit->first->vertex((fit->second))->point();
// points on the facet
const Point_3& p1 = fit->first->vertex((fit->second+1)&3)->point();
const Point_3& p2 = fit->first->vertex((fit->second+2)&3)->point();
const Point_3& p3 = fit->first->vertex((fit->second+3)&3)->point();
Vector_3 n = ( fit->second % 2 == 1) ?
CGAL::normal(p1, p2, p3) :
CGAL::normal(p1, p3, p2);
n = n /sqrt(n * n);
glNormal3d(n.x(), n.y(), n.z());
glVertex3d(p1.x(), p1.y(), p1.z());
glVertex3d(p2.x(), p2.y(), p2.z());
glVertex3d(p3.x(), p3.y(), p3.z());
++cnt2;
}
The way you extract facets is correct and will provide you a consistent orientation of the facets is you consider them from the same "side" of the surface. For example, consider a sphere embedded in a c2t3. If you only consider facets using tetrahedron inside the sphere then your function will do what you want. But since the iteration over facets does not guarantee you will not have tetrahedron outside the sphere your function will display incorrectly oriented facets.
A simple solution is to use the function CGAL::output_surface_facets_to_polyhedron to first create a polyhedron out of the c2t3 and use it for display.
Alternatively you can also look at the implementation which is not that complicated and mimic what is done.

How to determine if a set of coordinates are vertices of a regular polygon?

I have a working class that generates regular polygons given: polygon center and polygon radius and number of sides. Implementation details of the two private member functions here.
The class interface looks like this:
class RegularPolygon: public Closed_polyline{
public:
RegularPolygon(Point c, int r, int n)
: center(c), radius(r), sidesNumber(n)
{ generatePoly(); }
private:
Point center;
int radius;
int sidesNumber;
void generatePoly();
void rotateCoordinate(Point& axisOfRotation, Point& initial,
double angRads, int numberOfRotations);
};
Problem:
I am asked to implement a second way of generating regular polygons by using
a set of coordinates1. The constructor needs firstly to perform a validity check of the passed coordinates:
RegularPolygon(vector<Point>& vertices)
:center(), radius(), sideNumber()
{
// validity check of the elements of vertices
}
My initial thought is to:
Check if each pair of coordinates produces the same side length.
Check for each lines'(generated by a pair of coordinates) relative orientation. (they should be at an angle 360/polygon sides, from each other)
Question:
How could I check if all lines are properly oriented, i.e. their relative orientation? solved
Is there any standard algorithm that can determine if a set of coordinates are vertices of a regular polygon?
Note:
After checking [1] and all the question and answers regarding generating coordinates. I didn't found what I'm searching for.
1 In clockwise sequence, passed with the vector: vertices
All the additional files for compilation could be found: here. The FLTK could be found here.
Your task would be a lot simpler if you could find the center of your polygon. Then you would be able to check the distance from that center to each vertex to verify the placement of the vertices on the circle, and also to check the angles from the center to each individual vertex.
Fortunately, there is an easy formula for finding the center of a polygon: all you need to do is averaging the coordinates in both dimensions. With the center coordinates in hand, verify that
The distance from the center to each vertex is the same, and
The angle between consecutive vertices is the same, and that angle is equal to 2π/N radians
These two checks are sufficient to ensure that you have a regular polygon. You do not need to check the distances between consecutive vertices.

Tetris rotation C++

I am coding Tetris in Qt C++ at the moment. The game is almost completed and the only thing I need to add is the rotation. Now what I am struggling with, is the theory behind the rotation. Tetris has 7 different kind of stones ( I, S, Z, L, J, T, O ). Is there any algorithm or anything similar with the rotations from the different shapes ?
What I prefer not to do is having a switch case for 7 different shapes to handle the rotations. Also if a shape like L is rotated it has 4 different positions, which have to be handled different.
So the only thing I have thought of yet is to ask for the shape and then for the position. This would grant me some switches or else if's in a switch... Means a lot to type and a lot to check for the compiler.
P.S. My Stone structure looks like this:( Steine = german for stone, Art = shape )
struct position
{
int X;
int Y;
};
struct Steine
{
struct position* Position;
int Art;
};
You could use a 2D array of bool representation for each shape. Then when you rotate some specific array, you rotate that shape (maybe have the code at the initialization generate all the rotations) and check if any pixel is outside the Tetris borders or if the rotated shape should not be rotated because some of it's pixel would be on the same position as some already existing pixel from previous shapes.
Edit: Yeah, like you said yourself, best is to try on paper/paint to check it out (about the middle point for the rotation). For every shape you then end up with a 3x3 or 4x4. for 3x3 you rotate around it's middle point, for 4x4 around 1x1 for example (where index goes from 0 to 3). That is somewhat how I went for my Tetris 9 years ago or so.