Box2d Arrow Transformation - Java - java

I'm making an archer game with LibGdx supported with Box2d. Many of the Box2D tutorials are in C++ so some methods are different with Java.
I want to do is stick the arrow when it collide with a box.I found a tutorial but it is in C++ and I couldn't find a way to solve the issue. Actually it's a Math question. Here is the C++ code
//start with standard positions as for normal arrow creation
b2Vec2 vertices[4];
vertices[0].Set( -1.4f, 0 );
vertices[1].Set( 0, -0.1f );
vertices[2].Set( 0.6f, 0 );
vertices[3].Set( 0, 0.1f );
//now multiply by difference between arrow and target transforms
b2Transform diffTransform = b2MulT( si.targetBody->GetTransform(), si.arrowBody->GetTransform() );
for (int i = 0; i < 4; i++)
vertices[i] = b2Mul(diffTransform, vertices[i]);
b2PolygonShape polygonShape;
polygonShape.Set(vertices, 4);
//create a new fixture in the target body
b2FixtureDef fixtureDef;
fixtureDef.shape = &polygonShape;
fixtureDef.density = 1;
si.targetBody->CreateFixture( &fixtureDef );
//discard the original arrow body
m_world->DestroyBody( si.arrowBody );
The aim is when the arrow collide with a box, create a new arrow fixture add it to the box's body then remove the old arrow body. All done except transformation of arrow.
The problem is there is no b2MulT or b2Mul functions in Java. I want to transform the arrow with a position and angle of the old arrow's values when the collision occurs.

I am not conversant with box2d but given your program logic and a little bit of search it appears that b2MulT(x,y) is matrix multiplication of matrix x transpose with matrix y.
xT * y
If Java does not offer you an exact implementation of box2d, search for an efficient Java implementation of matrix class with matrix transpose multiplication.
That should hopefully do the trick.
BTW did you check the java port of box2d - http://www.jbox2d.org/
I think it should have the matrix class implemented- as matrix multiplication is the very basis of all transformations.

Related

Infinite vertical world

I am created two bodies in Box2d, they are: Player and Platform;
I wanted to create game like Doodle Jump, but I don't know how to create "infinite world with generating platforms";
There is my code where I am creating Array:
buckets = new Array<Bucket>();
for(int i=1;i<BUCKET_COUNT;i++){
buckets.add(new Bucket(W/2,BUCKET_MARGIN*i, world));
}
And this code where I am "Trying" to change position of each platform when camera position is change:
for(Bucket bucket : buckets){
if(cam.position.y - (cam.viewportHeight/2) > bucket.getBody().getPosition().y + 22/PPM){
bucket.repos(W/2,bucket.getBody().getPosition().y + BUCKET_MARGIN);
}
}
It works! But it changes last platform position to very far bottom:
Regarding how to create an infinite world?
Use the world instance shift origin method. In the Box2D 2.3.2 C++ library code, this is the b2World::ShiftOrigin(const b2Vec2& newOrigin) method. Here's an excerpt of this method's declaration along with its documentation:
/// Shift the world origin. Useful for large worlds.
/// The body shift formula is: position -= newOrigin
/// #param newOrigin the new origin with respect to the old origin
void ShiftOrigin(const b2Vec2& newOrigin);
In Java, you should be able to find a similar interface method.
With shift origin you keep the viewport to the physics world centered on (or near) the physical world origin (of 0, 0). This is basically the practical means of accomplishing what Yevhen Danchenko suggested in the comments.
A reason for using this is that the implementation of floating-point arithmetic which Box2D relies on, is itself not infinitely wide ranging nor infinitely accurate. So shifting things helps keep things closer to the origin where the floating-point values are more accurate and keeps things from going off the range of practically usable values assuming that you'll only ever be showing a limited range of x and y values.

How to draw star in java swing using fillPolygon

I'm having trouble setting the coordinate of the star are there any better solution for this. I cannot get the the correct shape. Can someone help me on this?
public void star(Graphics shapes)
{
shapes.setColor(color);
int[] x = {42,52,72,52,60,40,15,28,9,32,42};
int [] y = {38,62,68,80,105,85,102,75,58,20,38};
shapes.fillPolygon(x, y, 5);
}
Sun's implementation provides some custom Java 2D shapes like Rectangle, Oval, Polygon etc. but it's not enough. There are GUIs which require more custom shapes like Regular Polygon, Star and Regular polygon with rounded corners. The project provides some more shapes often used. All the classes implements Shape interface which allows user to use all the usual methods of Graphics2D like fill(), draw(), and create own shapes by combining them.
Regular Polygon Star
Edit:
Link
Honestly, I'd use the 2D Graphics shapes API, they allow you to "draw" a shape, which is simpler (IMHO) then using polygon. The advantage is, they are easy to paint and transform
Having said that, the problem you're actually having is the fact that you're not passing the right information to the fillPolygon method.
If you take a look at the JavaDocs for Graphics#fillPolygon, you'll note that the last parameter is the number of points:
nPoints - a the total number of points.
But you're passing 5, where there are actually 11 points in your array
Something like...
shapes.setColor(color);
int[] x = {42,52,72,52,60,40,15,28,9,32,42};
int [] y = {38,62,68,80,105,85,102,75,58,20,38};
shapes.fillPolygon(x, y, 11);
should now draw all the points, but some of your coordinates are slightly off, so you might want to check that
The second to last number of your Y should be 60 not 20
g2.setColor(color);
int[] x = {42,52,72,52,60,40,15,28,9,32,42};
int[] y = {38,62,68,80,105,85,102,75,58,60,38};
g2.fillPolygon(x , y, 11);
I'm having trouble setting the coordinate of the star are there any better solution for this
Check out Playing With Shapes. You should be able to use the ShapeUtils class to generate your shape.
This class will generate the points for you so you don't need to manage every pixel.
a star has 10 points ppl mind that not 11
setBackground(Color.black);
int[]x={250,150,0,150,100,250,400,350,500,350};
int[]y={100,200,200,300,400,300,400,300,200,200};
g.fillPolygon( (x),(y),10);
setForeground(Color.cyan);
this will help to draw a star with black bg and cyan foreground

Finding 4 corner polygon around contours, OpenCV

I am trying to find a coordinates of a shape(s) in a white-black image. I am using findContours method for contour finding and approxPolyDP for optimizing them to a polygon. The shape in the input image (see below) is an processed text, I need to find a 4 corner polygon for each field, which would fit around this shape using less outside space. ApproxPolyDP function rarely gives me a 4 corners (despite changing parameters), which I need to use to apply perspective transform on an original image and skip the deskewing algorythm and to crop out the text. How can i find the best fitting 4 corner polygons for each field (not rectangles)? I could not find any proper tutorial on how to do that, is it really hard? Below I present my current code in java; desired result; input; current output. NOTE: I would highly appreciate if you could give me a method where HoughLines are not involved, this method is slow (for mobile phones; that's why I am asking this question), but if it is the only one possibility you know to get the result I need, please, post it, it would be appreciated.
Code for finding current shape(s):
Mat mask = new Mat(src.size(), CvType.CV_8UC3, new Scalar(0,0,0));
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(src, contours, new Mat(), Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);
for (int i = 0 ; i < contours.size() ; i++)
{
int contourSize = (int)contours.get(i).total();
MatOfPoint2f curContour2f = new MatOfPoint2f(contours.get(i).toArray());
Imgproc.approxPolyDP(curContour2f, curContour2f, 0.04 * Imgproc.arcLength(curContour2f, true), true);
contours.set(i, new MatOfPoint(curContour2f.toArray()));
Imgproc.drawContours(mask, contours, i, new Scalar(0, 255, 0), 3);
}
Average input:
Desired result (it's not a rectangle, corners do not have to be 90 degrees, but here must be 4 of them):
Average current output:
Other output example: the input picture here was more detailed (with some gaps), so the output is much worse depending on what I want it to be. Polygons in other polygons is not a problem, but the main shape of a whole block has to much corners:
Thank you in advance.

worldToScreen() - How does it work?

I am reading an android tutorial for game development that explains how to convert in-game coordinates to actual pixels. Simple enough. This is done via function worldToScreen() as follows:
public Rect worldToScreen(float objectX, float objectY, float objectWidth, float objectHeight){
int left = (int) (screenCentreX - ((currentViewportWorldCentre.x - objectX) * pixelsPerMetreX));
int top = (int) (screenCentreY - ((currentViewportWorldCentre.y - objectY) * pixelsPerMetreY));
int right = (int) (left + (objectWidth * pixelsPerMetreX));
int bottom = (int) (top + (objectHeight * pixelsPerMetreY));
convertedRect.set(left, top, right, bottom);
return convertedRect;
}
It seems to return a rectangle object containing the four points that a square object would occupy.
Why does it use a square?
Why is it substracting top/left and adding bottom/right?
A thorough explanation will be much appreciated.
Answer to question 1
He's using a rectangle probably because it's a simple geometry object that is already implemented in Java and in most gaming libraries, like the one you are using (i can see he's using the Rect class).
Rectangle is also a common solution in 2D games when you want to implement simple collision detection for example.
Answer to question 2
You ask why he's adding bottom and right... But i can only see that he's adding top and left.
He's doing that because the y axis goes from up to down, and the x axis goes from left to right.
So to get the bottom point you have to add the y coordinate of the top point to the height of the rectangle.
Same for the right point, you have to add the x coordinate of the left point to the width of the rectangle.
In the hope that my Paint skills can come useful i made a drawing that probably will help you understand:
To make the drawing and my answer even more clear:
top + height = bottom
left + width = right
PS: "he" is the guy who made the tutorial that you're following.

What is the correct way of detecting collision amongst multiple objects?

This is something I'm trying to do for a university assignment and I'm quite new to it, but I've done a lot of reading on the subject. Please could someone to explain, in the simplest terms, how to do what I'm trying to do, so that I can understand what needs to happen?
I have an array of objects, each draw a circle to the screen; I have them bouncing within a bounding box but now I'd like them to collide.
I wrote the method below, which is working... but only just. The balls occasionally get stuck and 'jitter' on one another and I have no idea why this is happening. Also, I think I'm checking for more collisions than necessary(?).
void handleObjectCollision() {
for(int i = 0; i < _myBtns.length; i++) {
if(i != _id) {
float dx = _myBtns[i].x - x;
float dy = _myBtns[i].y - y;
float distance = sqrt(dx*dx + dy*dy);
if(distance < r * 2) {
xS = -xS;
yS = -yS;
// Debug
// println("Collision!");
}
}
}
A full paste of my class and pertaining segments can be found here: http://pastebin.com/eJawiHAE.
Also, here is an example I've been working from, http://processing.org/learning/topics/bouncybubbles.html.
I'm trying to achieve a simple bounce (reversal in speed?), without added physics or using vectors, as I want to be able to understand what's happening in it's simplest form, first.
Thank you.
You cannot just reverse the direction in which your object is moving, because the collision may happen almost from behind it, in which case the reversal will put it again in collision course against the object which collided with it. That explains the jitter that you see. You need to consider the direction from which the collision occurred, and adjust your direction vector accordingly, using the related physics formulas for what is known in physics as "elastic collisions".
Here, check this out: http://en.wikipedia.org/wiki/Elastic_collision

Categories

Resources