Draw a special shape on android canvas - java

I am struggling to draw this shape on an android canvas. I already used all what one could find in here. but it works on some angles and not on others.
Let's say that this shape can be drawn given a certain angle (in the example = 90°)
We also have the coordinates of the three points of the shape (A,B and C)
Here is the code I currently use :
// (cx,cy) is the point A
// (pos2LegX, pos2LegY) is the point C
// radDirection is the drawn example 90°
float radDirection = (float) (Math.toRadians(this.rad));
float pos2LegX = (float) (cx + radius * Math.sin(radDirection)) ;
float pos2LegY = (float) (cy - radius * Math.cos(radDirection)) ;
// (arcPosX, arcPosY) is the point B
float arcPosX = pos2LegX + (float) ((radius/2) * Math.abs(Math.cos(radDirection))) ;
float arcPosY = pos2LegY - (float) ((radius/2) * Math.abs(Math.sin(radDirection))) ;
// the rect to use with the drawers
final RectF oval = new RectF();
oval.set(pos2LegX , pos2LegY - radius/4, pos2LegX + radius/2, pos2LegY+ radius/4);
// draw the shape
// draw AC
canvas.drawLine(cx,cy,pos2LegX, pos2LegY ,paint);
// draw the arc CB
int startAngle = (int) (180 / Math.PI * Math.atan2(arcPosY - pos2LegY, arcPosX - pos2LegX));
canvas.drawArc(oval,startAngle,180,false,paint);
// draw BA
canvas.drawLine(arcPosX,arcPosY,cx,cy,paint);
This may work for example if radDirection = 180 but if radDirection = 000 it gives this :
But here, the shape should be in opposite direction with arc concave to the center cx, cy.
Any solution would be a big help for me.
Thanks in advance :)

Related

Java LibGDX relative value addition based on angle and position

I create a 2d game similar to a classic diepio. I created a system for positioning the player's barrel in a specific direction. The updated angle is sent to the server. When the player clicks, the server creates a missile. This only works correctly when the barrel is attached to the center of the player's body. When I want to move the barrel away from the center of the body, there is a problem. I don't know how to update the server-side position where the projectile spawns.
In the image below, the barrel rotates around the center of the player's body. I marked the missile's flight path with the red line.
On this image, the barrels also have a rotation axis in the player's center, but have been shifted to the side. The green line marked the route the missile should take. Unfortunately, I don't know how to do it correctly.
How to update the projectile's spawn point by a given distance (e.g. 10) from the basic distance (if the barrel was not moved) based on the player's angle of rotation and his position?
Projectile spawn method:
float angle = (float) ((player.getRotation() + 90) * Math.PI / 180f);
float forceX = (float) Math.cos(angle);
float forceY = (float) Math.sin(angle);
spawnProjectile(player.getPosition().x + (forceX * 3f), player.getPosition().y + (forceY * 3f));
If I understood your question correctly, you want to find the two points marked in orange in the following image:
Since you know the direction in which the missiles should fly (the red line), the distance from the center position (e.g. 10) and you know that there is a 90° angle between the movement vector of the missile (red line) and the connection line between the two starting positions of the missiles (marked as black line in the image) you can calculate the resulting positions like this:
float angle = (float) ((player.getRotation() + 90) * Math.PI / 180f);
float forceX = (float) Math.cos(angle);
float forceY = (float) Math.sin(angle);
// the center point (start of the red line in the image)
float centerX = player.getPosition().x + (forceX * 3f);
float centerY = player.getPosition().y + (forceY * 3f);
float offsetFromCenterDistanceFactor = 1f; // increase this value to increase the distance between the center of the player and the starting position of the missile
// the vector towards one of the starting positions
float offsetX1 = forceY * offsetFromCenterDistanceFactor;
float offsetY1 = -forceX * offsetFromCenterDistanceFactor;
// the vector towards the other starting position
float offsetX2 = -offsetX1;
float offsetY2 = -offsetY1;
//spawn the upper missile
spawnProjectile(centerX + offsetX1, centerY + offsetY1);
//spawn the lower missile
spawnProjectile(centerX + offsetX2, centerY + offsetY2);
For more detail on the calculation of the orthogonal vectors see this answer.

Creating 3d Ring in Android/Openegl with index buffer Objects

Right now im Creating an 3D game for android/OpenGL the sence is to fly through such 3D Rings made with index Buffer Objects as shown in the pictures.
My Problem: Actually my twisted Loop is generating the Coordinates like it should but if i translate it got squezzed,
because this is causing in this case the Y Coordinate not to match to the z Coordinate.
I tried around a few days finding a way to compensate this issue but succesless,
anyone of you could say me a way creating a translateble 3D Ring in OpenGL/android with or even without my basics that would Help me very well.
for (int y = 0; y < 32; y++) {
for (int x = 0; x < 32; x++) {
final float xPosR = 0.5f * (float) Math.cos((x) * move) ; //move = 2*Pi/31 : In this part the x coordinates are getting builded (after rotating they are actually the z coordinates)
final float yPosR = translationY + (float) Math.sin((y) * move) //translation = 1[enter image description here][1]/0 otherwise you could do it as translation with the modelmatrix
+ 0.5f * (float) Math.cos((x) * move) * (float) Math.cos((y) * move) ; //In this part the Y Coordinates are getting builded
final float zPosR = - (1f * (float) Math.cos((y) * move)) +
0.5f * (float) Math.cos((x) * move) * (float) Math.sin((y) * move); //In this part the z Coordinates are getting builded(after rotating they are actually the z coordinates)
//in the onDrawFrame Method it gets rotate 90 degree around the y-axis and translated -5 in the z-axis
heightMapVertexDataR[offsetR++] = xPosR;
heightMapVertexDataR[offsetR++] = yPosR;
heightMapVertexDataR[offsetR++] = zPosR;
Translation = 1
Translation = 0

The Projection Matrix Does More than Scaling, Right?

As I have it understood, a projection matrix scales a polygon depending on how far away or close it is from the camera. Though I might be completely wrong. My question is, how does the projection matrix "know" to show the sides of the following cube, as the camera moves, when the matrix is only supposed "scale" polygons?
Notice in the image, the cube is off to the right side of the screen, by moving the camera to the left. If the camera is moved in the opposite direction (to the right) in order to center the cube, the side of the cube will disappear as expected.
Here is my matrix code:
private void createProjectionMatrix(){
float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV/2f))) * aspectRatio);
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * NEAR_PLANE * FAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}
The function of a projection matrix (in the context of graphics APIs, such as OpenGL) is to transform vertex positions from view-space into clip-space.
Clip space is generally a unit box (although in D3D it's a half-unit box). If a vertex position after being transformed into clip-space does not lie within that unit box, then it is clipped. This is essentially how the system "knows" the cube is visible on the screen.

Drawing rectangles at an angle

What is a method in Java that draws a rectangle given the following:
The coordinates of the center of the square
The angle of the rectangle from vertical, in degrees
To draw a rectangle in the way you suggest you need to use the class AffineTransform. The class can be used to transform a shape in all manner of ways. To perform a rotation use:
int x = 200;
int y = 100;
int width = 50;
int height = 30;
double theta = Math.toRadians(45);
// create rect centred on the point we want to rotate it about
Rectangle2D rect = new Rectangle2D.Double(-width/2., -height/2., width, height);
AffineTransform transform = new AffineTransform();
transform.rotate(theta);
transform.translate(x, y);
// it's been while, you might have to perform the rotation and translate in the
// opposite order
Shape rotatedRect = transform.createTransformedShape(rect);
Graphics2D graphics = ...; // get it from whatever you're drawing to
graphics.draw(rotatedRect);
For the first point, you can just figure out the coordinates of the center of the square by using a distance formula, (int)Math.sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)); them divide by 2. you can do this for the width and height. I don't know enough about Java draw to give you better answers based on what was in your question but I hope that helps.
For the second, you would need to just create a polygon right?

Flipping a polygon that contains many polygons to create an upside down mirror of everything

I have created a polygon with 6 vertices. Lets call this one, outside polygon. Inside the outside polygon I created smaller polygons. I want to flip all of it vertically one point at the time.
I know the vertices of the outside polygon and I have an ArrayList<Polygon> for the inner polygons. I was able to flip the outside polygon. but how do I flipped the inner polygons keeping their relative positions in the new one? I know the center of the outside polygon and the flipped version.
correction: I needed to flip horizontal.
I flipped the outer polygon (triangle shape), and I was able to move the inner polygons. but the distance is incorrect. this is a picture of what I have done,
(https://docs.google.com/drawings/d/1cPYJqxTWVu5gSHFQyHxHWSTysNzxJvNuJIwsgCQInfc/edit) https://docs.google.com/drawings/d/1cPYJqxTWVu5gSHFQyHxHWSTysNzxJvNuJIwsgCQInfc/edit
I tried this:
for (Polygon p : polygonList) {
Polygon tempP = new Polygon(p.xpoints, p.ypoints, p.npoints);
firstPointinPolygon = new Point(p.xpoints[0], p.ypoints[0]);
// find frist point in the polygon
float adjacent = (float) firstPointinPolygon.getX() - 400;
float opposite = (float) firstPointinPolygon.getY() - 400;
float hypotenuse = (float) Math.sqrt(opposite * opposite + adjacent * adjacent);
float cosine = adjacent / hypotenuse;
float sine = opposite / hypotenuse;
float endX = 400 * cosine;
float endY = 400 * sine;
float endXDelta =400-endX;
float endYDelta=400-endY;
Polygon pM = move(tempP, endX, endY);
polygonListMirror.add(pM);
tempP = new Polygon();
}
public Polygon move(Polygon p, double xMove, double yMove) {
// Change the values of the points for the Polygon
for (int i = 0; i < p.xpoints.length; i++) {
p.xpoints[i] += xMove;
p.ypoints[i] += yMove;
}
return p;
}
But did not get the result, I expected. What am I doing wrong? The end result should be like the picture in this link:
(https://docs.google.com/drawings/d/1vYdWkCelWW1_NUypNhtmckBYfEMzCf6bMVtoB-AyPkw/edit) https://docs.google.com/drawings/d/1vYdWkCelWW1_NUypNhtmckBYfEMzCf6bMVtoB-AyPkw/edit
I think something like this will do it:
Polygon outerPolygon, oldOuterPolygon;
ArrayList<Polygon> innerPolygons;
// set up objects
for (Polygon polygon: innerPolygons)
{
for (int i = 0; i < polygon.ypoints.length; i++)
{
polygon.ypoints[i] = center(outerPolygon) - polygon.ypoints[i] + center(oldOuterPolygon);
}
}
If you just to flip it vertically where it stands, such that the y-coordinate of top-most and bottom-most points just switch around, center for both should be the same (thus you can just say 2*center).
I'm pretty sure you can replace center(outerPolygon) and center(oldOuterPolygon) with any point from the applicable Polygon, as long as both use the same point.

Categories

Resources