I am having trouble to make the camera rotate around my object. I am going to try to express myself as good as i can.
The objective is that when i load a new object and select it, (selecting it means that _selected_object points to the new object), the active camera points only to the center of the object(when analisis mode is activated), so the rotations and translation( translations just in the Z axis) are made around this object.
This is what i am trying right now:
_selected_camera->at.x=_selected_object->mtptr->M[3];
_selected_camera->at.y=_selected_object->mtptr->M[7];
_selected_camera->at.z=_selected_object->mtptr->M[11];
This code happens when the analisis mode (camera pointing and moving towards object) is activated. But when i move the object, the camera points nowhere or where it was initially pointing.
at.x from selected camera is the point towards the camera is looking. mtptr is the 4x4 matrix position of the object (in which object transformations are made), where last column has the center of the object.
If you're using legacy OpenGL, use gluLookAt.
Otherwise (pseudo code):
mat4 lookAt(vec3 eye, vec3 target, vec3 up)
{
//calculate axes based on the provided parameters
//cross product gives us the perpendicular vector
vec3 z = eye - target;
vec3 x = cross(up, z);
vec3 y = cross(z, x);
//normalize to make unit vectors
normalize(x);
normalize(y);
normalize(z);
//translation vector
//based on the angle between the eye vector (camera position) and the axes
//hint: angle = dot(a, b) -> see: https://en.wikipedia.org/wiki/Dot_product
vec3 t = {
-dot(eye, x),
-dot(eye, y),
-dot(eye, z)
};
return { //a combined scale, skew, rotation and translation matrix
x[0], x[1], x[2], t[0],
y[0], y[1], y[2], t[1],
z[0], z[1], z[2], t[2],
0, 0, 0, 1
};
}
Multiply the resulting (view) matrix with a projection matrix (ortho, perspective).
Related
How do we find the intersection of the interiors of n squares that have sides parallel to the x and y axes given their centers and side lengths?
The input is the number of squares followed by that many descriptions of squares. The description of each square is the x and y coordinates of its center and its side length. For example:
3
5 11 10
7 9 10
10 6 8
describes three squares, starting with one centered at (5, 11) with side length 10.
An algorithm to find the intersection of the interiors of squares (with sides parallel to the x and y axes) given by their centers and lengths is:
Convert the center (the point (x, y)) and length (l) of the first square to the x coordinates of the left edge (x−l/2) and the right edge (x+l/2) and the y coordinates of the bottom edge (y−l/2), and the top edge (y+l/2). Keep those as the left, right, bottom, and top.
For each following square:
Convert its center and length to coordinates as above.
Figure out which x coordinate is greater, the old left or the new left edge, and keep that as the new left.
Figure out which x coordinate is lesser, the old right or the new right edge, and keep that as the new right.
Figure out which y coordinate is greater, the old bottom or the new bottom edge, and keep that as the new bottom.
Figure out which y coordinate is lesser, the old top or the new top edge, and keep that as the new top.
After processing all squares, left, right, bottom, and top are the coordinates of the rectangle bounding the area that is inside all of the squares. (If right < left or top < bottom, the intersection is empty. Otherwise, if right = left or top = bottom, the intersection is a line [if only one is true] or a point [if both are true].)
Here is a simple function to calculate the intersection between two rectangles. A square is a rectangle, so it can be used for squares. I assume that the rectangles height and width are parallel to the y and x axis.
struct point { double x, y; };
struct rectangle { struct point a, b; };
double max(double a, double b) { return a>b ? a : b; }
double min(double a, double b) { return a<b ? a : b; }
// Calculate the intersection of r1 and r2 and store the result in output
// Assumes that a.x < b.x and a.y < b.y for r1 and r2
// Returns NULL if there is no intersection
// Will always modify output. Do do NOT read output if this function returns NULL
struct rectangle *intersection(
struct rectangle *output,
const struct rectangle *r1,
const struct rectangle *r2)
{
output->a.x = max(r1->a.x, r2->a.x);
output->b.x = min(r1->b.x, r2->b.x);
if(output->a.x > output->b.x) return NULL;
output->a.y = max(r1->a.y, r2->a.y);
output->b.y = min(r1->b.y, r2->b.y);
if(output->a.y > output->b.y) return NULL;
return output;
}
I'm trying to rotate a 2D pixel matrix, but nothing actually happens.
my origin is a stored bitmap[w x h x 3].
why isn't the shown image being rotated?
Here's the display function:
void display()
{
uint32_t i = 0,j = 0,k = 0;
unsigned char pixels[WINDOW_WIDTH * WINDOW_HEIGHT * 3];
memset(pixels, 0, sizeof(pixels));
for(j = bitmap_h -1; j > 0; j--) {
for(i = 0; i < bitmap_w; i++) {
pixels[k++]=bitmap[j][i].r;
pixels[k++]=bitmap[j][i].g;
pixels[k++]=bitmap[j][i].b;
}
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glRotatef(90,0,0,1);
glDrawPixels(g_img.descriptor.size_w, g_img.descriptor.size_h, GL_RGB, GL_UNSIGNED_BYTE, &pixels);
glutSwapBuffers();
}
First and foremost glDrawPixels should not be used. The problem you have is one of the reasons. The convoluted rules by which glDrawPixels operate are too vast to outline here, let's just say, that there's a so called "raster position" in your window, at which glDrawPixels will place the lower left corner of the image it draws. No transformation whatsoever will be applied to the image.
However when setting the raster position, that's when transformations get applied. And should, for whatever reason, the raster position lie outside the visible window nothing will get drawn at all.
Solution: Don't use glDrawPixels. Don't use glDrawPixels. DON'T USE glDrawPixels. I repeat DON'T USE glDrawPixels. It's best you completely forget that this function actually exists in legacy OpenGL.
Use a textured quad instead. That will also transform properly.
I did something similar. I'm creating a 3D space shooter game using OpenGL/C++. For one of my levels, I have a bunch of asteroids/rocks in the background each rotating and moving at a random speed.
I did this by taking the asteroid bitmap image and creating a texture. Then I applied the texture to a square (glBegin(GL_QUADS)). Each time I draw the square, I multiply each of the vertex coordinates (glVertex3f(x, y, z)) with a rotation matrix.
|cos0 -sin0|
|sin0 cos0 |
0 is the theta angle. I store this angle as part of my Asteroid class. each iteration I increment it by a value, depending on how fast I want the asteroid to spin. It works great.
I have a set of data points, which I want to test if they lie on a logarithmic spiral arm for given parameters. The following program seems to work, but does not return any points close to the center of my plane, which contains all the data points. The image attached shows that my program does not seem to find any points which overlap with the spiral near the center. Here is the link :
http://imgur.com/QbNPg5S. Moreover, it seems to show two spirals in the overlapped points, which is another issue.
int main(){
float radial[10000]={0}, angle[10000]={0}; // my points of interest
float theta, r_sp; // radius and the angle theta for the spiral
Construct a spiral which lies in the same plane as my sources (green in the image)
for (j=0;j<=PI*10; j++){
theta=j*3./10;
r_sp=a_sp*exp(b_sp*theta);
Calculating the radial and angular components from x and y given coordinates (read from a file)
for (m=0;m<=30;m++){
radial[m]=pow((x_comp*x_comp+y_comp*y_comp),0.5);
angle[m]= atan2f(y_comp, x_comp);
Change the range from [ -pi, pi] to [0, 2*pi] consistent with "theta" of spiral
if (angle[m] < 0.){
angle[m]=angle[m]+PI;
}
Check if the point (radial and angle) lies on/around the spiral. For the realistic effect, I am considering the points at a radial distance "dr=0.5" (jitter) away from the "r_sp" value of the spiral.
if (fabs(r_sp-radial[m]) <=0.5 && fabs(theta-angle[m]) <= 1.0e-2){
printf("%f\t%f\t%f\t%f\n",l[k],b[k],ns[k],radial[m]);
}
}
}
return 0;
}
You check the conditions only for the first turn of spiral that lies in angle range 0..2*Pi.
At first you have to estimate potential turn number from r = radial[m]
r=a*exp(b*t)
r/a=exp(b*t)
ln(r/a)=b*t
t = ln(r/a) / b
turnnumber = Floor(ln(r/a) / b)
Now you can use
angle[m] = YourAngleFromArctan + 2 * Pi * turnnumber
to compare
I've got an array of strings that I'd like to draw as a giant spiral. I only have a very, very rough idea of where to begin. First, I will probably need to break the strings into an array of individual characters? Next, I will probably need to apply the following geometry in order to generate the spiral shape?
float r = 0;
float theta = 0;
void setup() {
size(200,200);
background(255);
}
void draw() {
float x = r * cos(theta);
float y = r * sin(theta);
noStroke();
fill(0);
ellipse(x+width/2, y+height/2, 6, 6);
theta += 0.01;
r += 0.05;
}
However, I don't know how to step through my array of characters in order to draw them in a spiral-like format. I apologize for the lack of clarity. Any suggestions would be awesome! I'm very new to all of this (clearly).
Your code for creating the spiral is a good idea. One way to create rotated text would be using rotate(), combined with text(). You would have a for loop, iterate through your character array, increment the radius, and draw your text that way. Note that rotate() has a cumulative effect. Something like:
String str = "asdflkkjsahfdlkadshflkahdslkfajsdf";
float radius = 0;
//so we are rotating around the center, rather than (0,0):
translate(width/2, height/2);
for (int i = 0; i < str.length(); i++) {
radius += 2;
// taken out because of non-constant spacing at large radius:
//rotate(0.5);
// this should give constant spacing, no matter the radius
// change 10 to some other number for a different spacing.
rotate(10/radius);
// drawing at (0,radius) because we're drawing onto a rotated canvas
text(str.charAt(i), 0, radius);
}
You may want to have the angle change be a function of radius, because at large radii, the letters are spaced very far apart. One way to do this would be using the equation s = rθ, where s is the arclength (in this case, distance between letters), r is radius, and θ is the angle change. If you want a constant distance between letters, regardless of radius, then θ would have to be proportional to 1/r. And of course, you can tweak the hard-coded values to your liking.
Also: the rotate() and translate() methods are undone at the end of draw(), so if you aren't doing anything after this code, then it's okay to leave it as is. If you do want to draw more stuff after, then you'll have to undo the rotation and translation manually before you draw anything else.
Edit: I just realized that I assumed you wanted the letters to be rotated as well, and not just positioned in a spiral but still oriented normally. In that case, you could use your existing code and replace the ellipse(...) with text(str.charAt(...)...), with appropriate parameters of course.
i'm trying to do something in C, I'm building a server that will receive a Latitude and Longitude coordinate, -23.0001, -43.3417 to be exact, i'm trying to make a 10km radius circle around that coordinate, is it possible ? I gave up trying to make a circle and was trying to make a square with 20km sides, where the coordinate I gave is the center, but I keep failing, here is what I'm trying
Quad *cria_quadrado_complex(Coords *b)
{
Quad* a = (Quad*) malloc(sizeof(Quad));
a->x1 = b->x + 0.0433;
a->x2 = b->x + 0.0587;
a->y1 = b->y + 0.0433;
a->y2 = b->y + 0.0490;
return a;
}
the structs used are:
struct coordenadas
{
double x,
y;
};
struct quadrado
{
double x1,
x2,
y1,
y2;
};
typedef struct coordenadas Coords;
typedef struct quadrado Quad;
those 0.0 something values are values I measured from google maps but they are faar from the center and dindn't work, is there a better way to do that ? help
ps -23.0001, -43.3417 are coordinates from google maps
here is an example of what i'm trying to do:
1---------- 1 : top coordinate of the square
-----------
-----C----- C : center coordinate (-23.0001, -43.3417)
-----------
----------2 2 : bottom coordinate of the square
1 and 2 I want to generate automatically with the center coordinates, they will be away from the center so the sides of the square is 10 km
It certainly is possible, but you'll want to get the right formula. A good start might be to read http://www.movable-type.co.uk/scripts/gis-faq-5.1.html.
You don't say why you're doing this in C, and I can't tell if you need to calculate this for an arbitrary lat/lng or just for the one that you give. If you can do it in another language or find a C library that will process KML, and if you only need the one set of coordinates to work, you can use the tool at http://www.freemaptools.com/radius-around-point.htm to generate KML or a Google Maps Static API URL. If you're only concerned about the single pair of coordinates you specify, a hardcoded KML file may be the way to go.