Can I rotate 3D car object - android

Can I use a rotating animation without using anyOpenGL or any 3rd pary tool. I just want to apply a clockwise rotating 3D car object in a fix layout.yout.

Unless you have some sort of sprite animation sequence that emulates a 3D car then I don't see how you can do it to be honest. I might be wrong though and may have missed something in android but to me this is a classic openGL situation.
By sprite animation I also mean any sort of 2D sequence of images, for example animated gifs.

1) Well, you first have to set the car in 3D space;
To model a 3D object, you must define all the vertices of the car as if you were modeling with points and after , linking this point you get the car in wireframe.
Pont A {x = 3, y = 10, z = 8}
Point B {x = 5, y = 12, z = 2}
Point C {x = 6, y = 40, z = 6}
Point D {x = 7, y = 12, z = 3}
Point E {x = 3, y = 10, z = 8}
...
2) After modeling the car in points, you must define the links of points to form lines, there you have called wireframe modeling, if you want to modeling shapes is different, but with the wireframe already a good idea of the object in the real world.
Line AB = Point A -> Point B
Line BC = Point B -> Point C
3) To spin perfectly the car, you should position it in the center of coordinates,applying in each point the formula translation T with measure the match the distance to the subject from the center at the origin of the axes.
New point x:
x = x - Tx
New point y;
y = y - Ty
New point z:
z = z - Tz
4) With the car in position to spin it into an angle "g" should be applied to each point the rotation transformation, the formula is:
 
Find the new point x:
xt = (x * 1) (* y 0) (z * 0);
Find the new point y:
yt = (X * 0) (y * Math.cos (g)) (z * (Math.sin-(g)));
Find the new point z:
zt = (X * 0) (y * Math.sin (g)) (z * Math.cos (g));
5) After applying the rotation effect, you must return the object to its point of origin, making a reverse translation to step 3.
New point x:
x = Tx x
New point y;
y = y Ty
New point z:
z = z Tz
This is a roughly explanation but is the most basic way, of course it has more complex formulas that are faster these changes, but to become more didactic I put this way.

Related

opengl object vibrate after moving a distance

I have an object which moves on a terrain and a third person camera follow it, after I move it for some distance in different directions it begin to shaking or vibrating even if it is not moving and the camera rotates around it, this is the moving code of the object
double& delta = engine.getDeltaTime();
GLfloat velocity = delta * movementSpeed;
glm::vec3 t(glm::vec3(0, 0, 1) * (velocity * 3.0f));
//translate the objet atri before rendering
matrix = glm::translate(matrix, t);
//get the forward vetor of the matrix
glm::vec3 f(matrix[2][0], matrix[2][1], matrix[2][2]);
f = glm::normalize(f);
f = f * (velocity * 3.0f);
f = -f;
camera.translate(f);
and the camera rotation is
void Camera::rotate(GLfloat xoffset, GLfloat yoffset, glm::vec3& c, double& delta, GLboolean constrainpitch) {
xoffset *= (delta * this->rotSpeed);
yoffset *= (delta * this->rotSpeed);
pitch += yoffset;
yaw += xoffset;
if (constrainpitch) {
if (pitch >= maxPitch) {
pitch = maxPitch;
yoffset = 0;
}
if (pitch <= minPitch) {
pitch = minPitch;
yoffset = 0;
}
}
glm::quat Qx(glm::angleAxis(glm::radians(yoffset), glm::vec3(1.0f, 0.0f, 0.0f)));
glm::quat Qy(glm::angleAxis(glm::radians(xoffset), glm::vec3(0.0f, 1.0f, 0.0f)));
glm::mat4 rotX = glm::mat4_cast(Qx);
glm::mat4 rotY = glm::mat4_cast(Qy);
view = glm::translate(view, c);
view = rotX * view;
view = view * rotY;
view = glm::translate(view, -c);
}
float is sometimes not enough.
I use double precision matrices on CPU side to avoid such problems. But as you are on Android it might not be possible. For GPU use floats again as there are no 64bit interpolators yet.
Big numbers are usually the problem
If your world is big then you are passing big numbers into the equations multiplying any errors and only at the final stage the stuff is translated relative to camera position meaning the errors stay multiplied but the numbers got clamped so error/data ratio got big.
To lower this problem before rendering convert all vertexes to coordinate system with origin at or near your camera. You can ignore rotations just offset the positions.
This way you will got higher errors only far away from camera which is with perspective not visible anyway... For more info see:
ray and ellipsoid intersection accuracy improvement
Use cumulative transform matrix instead of Euler angles
for more info see Understanding 4x4 homogenous transform matrices and all the links at bottom of that answer.
This sounds like a numerical effect to me. Even small offsets coming from your game object will influence the rotation of the following camera with small movements / rotations and it looks like a vibrating object / camera.
So what you can do is:
Check if the movement above a threshold value before calculating a new rotation for your camera
When you are above this threshold: do a linear interpolation between the old and the new rotation using the lerp-algorithm for the quaternion ( see this unity answer to get a better understanding how your code can look like: Unity lerp discussion )

android Dividing circle into N equal parts and know the coordinates of each dividing point

I have requirement that a circle should be divided into N equal parts based on number(2,3...n. But I want the coordinates of dividing points.
I have a circle whose centre(x,y) and radius(150) are known.
Question:
Is there any formula which gives me the coordinates of dividing points as shown in figure. Can anyone please tell me the formula. I want to implement it in Java.
Circle image for refrence:
I have already accepted answer... the formula works perfectly.
Here is the solution coded in Java. It will help other developers.
private int x[]; // Class variable
private int y[]; // Class variable
private void getPoints(int x0,int y0,int r,int noOfDividingPoints)
{
double angle = 0;
x = new int[noOfDividingPoints];
y = new int[noOfDividingPoints];
for(int i = 0 ; i < noOfDividingPoints ;i++)
{
angle = i * (360/noOfDividingPoints);
x[i] = (int) (x0 + r * Math.cos(Math.toRadians(angle)));
y[i] = (int) (y0 + r * Math.sin(Math.toRadians(angle)));
}
for(int i = 0 ; i < noOfDividingPoints ;i++)
{
Log.v("x",""+i+": "+x[i]);
Log.v("y",""+i+": "+y[i]);
}
}
Where x0 and y0 are co ordinates of circle's centre.and r is radius.
In my case:
Input x0 = 0 , y0 = 0 and r = 150 , noOfDividingPoints = 5
output
point1: (150,0)
point2: (46,142)
point3: (-121,88)
point4: (-121,-88)
point5: (46,-142)
You need to convert between polar and Cartesian coordinates. The angle you need is the angle between the (imaginary) vertical line that splits the circle in half and the line that connects the center with the circle's boundary. With this formula you can calculate the X and Y offsets from the center.
In your example image the first angle is 0, and the second one is 360/n. Each next is i*(360/n) where i is the index of the current line you need to draw. Applying this will give you the X and Y offsets in a clockwise order (and you can just add them to the X and Y coordinates of the center to find the coordinates of each point)
EDIT: some kind of pseudo-code:
//x0, y0 - center's coordinates
for(i = 1 to n)
{
angle = i * (360/n);
point.x = x0 + r * cos(angle);
point.y = y0 + r * sin(angle);
}

Drawing an arrow head in android

I am trying to draw an arrow to point to objects in am image. I have been able to write code to draw the line but cant seem to be able to find a way to draw the arrowhead.The code I wrote to draw a dragabble line is as follows.I need to draw an arrowhead on ACTION_UP event to the direction in which the line is pointing
if(event.getAction() ==MotionEvent.ACTION_DOWN) {
if (count==1){
x1 = event.getX();
y1 = event.getY();
System.out.println(count+"count of value a;skd");
Toast.makeText(getApplicationContext(), ""+(radius+count), Toast.LENGTH_LONG).show();
Log.i(TAG, "coordinate x1 : "+String.valueOf(x1)+" y1 : "+String.valueOf(y1));
}
}
else if(event.getAction() ==MotionEvent.ACTION_MOVE){
imageView.setImageBitmap(bmp2);
x2 = event.getX();
y2 = event.getY();
posX=(float)(x1+x2)/2;
posY=(float)(y1+y2)/2;
radius=(float) Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))/2;
onDraw();
Toast.makeText(getApplicationContext(), ""+radius, Toast.LENGTH_LONG).show();
}
Hi, for anyone still needing help .This is how I did it in the end
float h=(float) 30.0;
float phi = (float) Math.atan2(y2 - y1, x2 - x1);
float angle1 = (float) (phi - Math.PI / 6);
float angle2 = (float) (phi + Math.PI / 6);
float x3 = (float) (x2 - h * Math.cos(angle1));
float x4 = (float) (x2 - h * Math.cos(angle2));
float y3 = (float) (y2 - h * Math.sin(angle1));
float y4 = (float) (y2 - h * Math.sin(angle2));
c.drawLine(x1, y1,x2,y2 ,pnt);
c.drawLine(x2, y2,x3,y3 ,pnt);
c.drawLine(x2, y2,x4,y4 ,pnt);
I got help from the accepted answer and ios section in stackoverflow
How I would do this is to find the slope of the line, which is drawn between two points(start and end). The slope would be (dy/dx), and that would be a good start point for your arrow. Assuming you want the base of the arrowhead to be perpendicular to the line of the arrow, to find the slope of the base you would find the opposite reciprocal of the slope of the line. for example, lets say that your line has a slope of 2. The slope for the base of your triangle would be (-1/2), because you do (1/(oldslope)) and multiply by -1. I don't know android very well, but if I remember correctly, in Java, you would use a drawPolygon method, and you would have to specify 4 points(3 unique and 1 the same as the first to close it). Given the slope of the base of the tip, we can get our first two points and our final point. You should know before you start the dimensions of the arrowhead you wish to draw, so in this case b will be the length of your baseline. If you take ϴ=arctan(dy/dx), that will give you an angle between the x axis and your baseline. With that ϴ value, you can do ydif = b*sin(ϴ) to get the difference in y value between the two base corners of your arrow. Doing the same thing but with xdif = b*cos(ϴ) gives you the difference in the x value between the two base points. If the location of the final point of the line that the user drew is, say, (x1, y1), then the locations of the basepoints of the triangle would be (x1-(xdif/2), y1-(ydif/2)) and (x1+(xdif/2), y1+(ydif/2)). These two points, p1 and p2, are the first, second, and fourth points in the draw polygon method. To find the third point, we need to find the angle of the original line, by doing ϴ=arctan(dy/dx), this time using your original dy/dx. with that angle. Before we finish the actual calculation of the point, you first have to know how far from the end of your line the tip of the arrow should actually be, in my case, I will use the var h and h = 10. To get the cordinate, (x,y), assuming the cordinate for the line tip is (x1, y1)you would do (x1+hcosϴ, y1+hsinϴ). Use that for the third value in drawPolygon(), and you should be done. sorry if I kind of rushed at the end, I got kind of tired of typing, comment if you need help.
If you managed to draw a line from the input event, you might additionally draw a triangle on its end indicating the direction.
On another project I drew a square everytime a magnetic point on a grid was touched (as you can see here) Sorry I can not provide you any sample code right now. But if that's a suitable approach for you, I might post it later.
Here is a good code, its not mine, It was a Java Graphics2D code that I converted to Canvas. All credit go to the original guy/lady who wrote it
private void drawArrowHead(Canvas canvas, Point tip, Point tail)
{
double dy = tip.y - tail.y;
double dx = tip.x - tail.x;
double theta = Math.atan2(dy, dx);
int tempX = tip.x ,tempY = tip.y;
//make arrow touch the circle
if(tip.x>tail.x && tip.y==tail.y)
{
tempX = (tip.x-10);
}
else if(tip.x<tail.x && tip.y==tail.y)
{
tempX = (tip.x+10);
}
else if(tip.y>tail.y && tip.x==tail.x)
{
tempY = (tip.y-10);
}
else if(tip.y<tail.y && tip.x==tail.x)
{
tempY = (tip.y+10);
}
else if(tip.x>tail.x || tip.x<tail.x)
{
int rCosTheta = (int) ((10)*Math.cos(theta)) ;
int xx = tip.x - rCosTheta;
int yy = (int) ((xx-tip.x)*(dy/dx) + tip.y);
tempX = xx;
tempY = yy;
}
double x, y, rho = theta + phi;
for(int j = 0; j < 2; j++)
{
x = tempX - arrowLength * Math.cos(rho);
y = tempY - arrowLength * Math.sin(rho);
canvas.drawLine(tempX,tempY,(int)x,(int)y,this.paint);
rho = theta - phi;
}
}
Just call this for both sides of your line and it will draw an arrow at each side!

Draw perpendicular line to given line on canvas android

I drawn line passing through points - (x1,y1) , (x2,y2)
Now i want to draw another line perpendicular to this line with same length.
Please guide me for this ..
Think of your line as a vector from (x1,y1) to (x2,y2). Then we get the x and y components of this vector according to
vX = x2-x1
vY = y2-y1
The vector of equal size to this but perpendicular to it in the plane has x and y components
vXP = -(y2-y1)
vYP = x2-x1
you can verify these 2 vectors are perpendicular by taking the scalar product of the 2 vectors which will be zero. Now you have your vector of equal length and perpendicular to your first vector, you simply need to decide the start point of your line. We will call that (a,b). Then using your start point, the end point of your line is given by
(a - (y2-y1), b + (x2-x1))
or if you want it to point in the reverse direction (still perpendicular) it will be
(a + (y2-y1), b - (x2-x1))
Well, it's simple maths :
int dx = x2 - x1;
int dy = y2 - y1;
int ox,oy; // Origin of new line
//...
drawLine( ox, oy, ox+dy, oy-dx) // This line will be perpendicular to original one
All you have to do is to choose the origin.
For example, if you want that the lines cuts at their center, let :
ox = x1 + (dx - dy) / 2;
oy = y1 + (dx + dy) / 2;

How can i draw a cylinder in OpenGL-es on Android?

Can any one help me to draw a cylinder in OpenGL-es android. Whatever i draw its look like a rectangle.
I would appreciate any tips or link.
Here is the code i've tried:
int VERTICES=180; // more than needed
float coords[] = new float[VERTICES * 3];
float theta = 0;
for (int i = 0; i < VERTICES * 3; i += 3) {
coords[i + 0] = (float) Math.cos(theta);
coords[i + 1] = (float) Math.sin(theta);
coords[i + 2] = 0;
_vertexBuffer.put(coords[i + 0]);
_vertexBuffer.put(coords[i + 1]);
_vertexBuffer.put(coords[i + 2]);
theta += Math.PI / 90;
}
This will only draw a circle. A cylinder is more complicated as you will need to define vertices in a translated z plane. And define them with correct normals (either facing in as if you were inside the cylinder -ie a tunnel or out as in looking at a pipe) which is the trickier part.
I'm currently doing this now (which is what brought me here) and have the cylinder drawn but pretty sure my normals are incorrect as my lighting looks a bit off. I'll post some code when I figure it out.
Edit : realized the code also doesn't actually draw a circle. Here is how to do that (in 2D) :
R = Radius
NUM_VERTICES = Number of vertices you want to use in circle
delta = (Math.PI / 180) * (360 / NUM_VERTICES); //get delta in radians between vertex definition
for i = 0 ; i < NUM_VERTICES ; i ++
x = R * cos(Delta * i)
y = R * sin(Delta * i))
vertices[i] = x; vertices[i+1] = y; vertices[i+2] = 0;
end for
//note may need to redefine the original vertex to complete the circle depending on which GL draw type you are using. If so just take the arg to sin / cos to be 0 to complete the loop
Last Edit* : just realized I was overcomplicating the normals by re-using some calculate normal from triangle code I had. Instead I realized how simple the normal calculation is for a cylinder if you consider the the origin 0,0 to be the center of each circular strip. The normal will be = vertex position scaled to length 1. for normals facing in on a cylinder (ie tunnel) the x,y values would be inverted (this is a assuming you are looking down the -z axis).

Categories

Resources