I am a newbie learner to JBox2D. I was just trying JBox2D for the first time on Android(I know Android development and I'm good in it) because my project needed physics.
Now, the tutorials and "Official User Manual" of Box2D said that negative gravity would result in objects being attracted downwards. But, in my case the object is being attracted upwards when I set Vec2's second parameter to be negative! Weird.
Here's the code which results in a circle shape going up on its own:
The Gravity:
Vec2 gravity = new Vec2(0.0f, -50.0f);
boolean doSleep = true;
world = new World(gravity, doSleep);
The circle shape is being made by following code:
//body definition
BodyDef bd = new BodyDef();
bd.position.set(200, 500);
bd.type = BodyType.DYNAMIC;
//define shape of the body.
CircleShape cs = new CircleShape();
cs.m_radius = 10f;
//define fixture of the body.
FixtureDef fd = new FixtureDef();
fd.shape = cs;
fd.density = 1f;
fd.friction = 0.2f;
fd.restitution = 0.8f;
//create the body and add fixture to it
body = world.createBody(bd);
body.createFixture(fd);
And I'm using SurfaceView canvas to draw:
canvas.drawCircle(body.getPosition().x, body.getPosition().y, 10, paint);
And stepp-ing as follows:
float timeStep = 1.0f / 60.f;
int velocityIterations = 6;
int positionIterations = 2;
world.step(timeStep, velocityIterations, positionIterations);
So, what's wrong within my code? I am unable to identify the mistake I've done.
Also,
I'm making a tennis-like 2D game on Android for which I'll be using JBox2D. So, can anybody tell me a tutorial/book on JBox2D? Though I googled vigorously, I couldn't find a good tutorial on it. (Though Box2D seems to be much popular instead of JBox2D)
I would be extremely grateful if someone could help me out here. Thank you.
In Box2D there is standard coordinate system: Y directed up, X to the right. In the graphic systems, usual, coordinate system has Y directed down, because window has static top-left corner. Looks like at your graphic system all the same. So, what in Box2D is moving down, you see as moving up.
It is the irritable problem, and directing gravity up is not the best solution. If you change only gravity, then you will need think about up-down problem in many other cases, for example, when define bodies, apply forces and so on. The most irritable, that it is not easy to understand, how physic coordinates conform graphic (for example, in one of my projects I had to draw points on paper, then turn paper back, rotate on 180 grades and look on the light :).
You can't change Box2D coordinate system, but, most likely, you can easy change coordinate system of graphic system by changing translation matrix. For example, in OpenGL it looks like this:
glScalef(1.0, -1.0, 1.0);
But take attention, after this, all that have positive Y coordinate will be not visible on the screen (it will be above the top edge of the window). So, you will need work with negative coordinates. If you don't want this, you can translate matrix down like this:
glTranslatef(0.0, -windowHeight.0, 0.0)
But before, think what to do if window would be resized.
About second question. I doubt whether you can find anywhere tutorial or book for JBox2D. JBox2D is port of Box2D (that means, it is exact copy of Box2D), and writing special book for it looks strange. Learn Box2D, and you will have no problem with JBox2D. For example, you can look there.
Related
I have a lot of rectangles, described using the top-left coordinate, where x increases as it goes right and y increases as it goes down. I need to find out whether the rectangles intersect with each other.
I drew my rectangles using Inkscape, and I computed them with x and y coordinates (the top-left of the rectangle), height, width, and stroke-width from the SVG file so there were a lot of computations I've done prior to this method so I was kind of assuming that I have to set a threshold or something alike before I could actually see if they intersect (which explains why I placed 0.001 in my code, but it was just a guess/test value).
When I drew them, I placed their x,y coordinates and I don't think they intersect but I'm assuming that the stroke-width would have an effect on their x,y coordinates.
I thought I could use Java.Awt.Rectangle#intersects method in Android but apparently, I can't. I also cannot use android.graphics.Rect#intersects because I am dealing with double and it only allows integers and I also do not need it to be drawn on my screen.
I have tried to create my own code for this based on what I've read online but the output isn't as what I expected, some of it are actually correct but there were a few errors. Below is the code I've tried.
// x1_1, y1_1 = top-left coordinate of r1
// x1_2, y1_2 = top-right coordinate of r1
// x2_1, y2_1 = top-left coordinate of r2
// x2_2, y2_2 = top-right coordinate of r2
double a1 = Math.abs(x1_1-x2_2);
double a2 = Math.abs(x1_2-x2_1);
double b1 = Math.abs(y1_1 - y2_2);
double b2 = Math.abs(y1_2 - y2_1);
return !(a1>0.001 && a2>0.001 && b1>0.001 && b2>0.001);
Oftentimes, I could see that the x coordinates are indeed similar or close to each other, but based on the actual image, they are not intersecting. Here is a demonstration:
In this image, I drew a red line to describe that the two rectangles "kind of intersect" in terms of the code, which does not satisfy an actual intersection. I think it was the fact that I had to check the y-coordinates as well but I'm no longer sure of how to do that because I think I have to check a range of values.
I hope I could get some help as to see if a rectangle intersects another or is beside another rectangle. Perhaps using a library or a modification on my existing code because it is not working as it should. Thanks in advance!
You can use Rect to work with rectangles, and check intersection in particular:
Rect r1 = new Rect(left1, top1, right1, bottom1);
Rect r2 = new Rect(left2, top2, right2, bottom2);
boolean result = r1.intersect(r2);
If you need float coordinates, you can use RectF
I have a game world in which the player rotates around a point (like a planet). How can I rotate a body around a center point? I also want to somehow be able to use something like the actor classes interpolation for moving things, is that possible? Thanks!
You can rotate via vector2 easly.
Vector2 vectorbody = new Vector2(50f, 50f);
Vector2 vectorcenter = new Vector2(100f,100f);
Vector2 vectordis= vectorbody.cpy().sub(vectorcenter);//Displacement vector center to body
vectordis.setAngle( vectordis.angle() + rotatespeed );//Rotate speed can be negative that means it will rotates to other side.
vectordis.add(vectorcenter); //vectordis now became rotated vectorbody
vectorbody.set(vectordis); //vectorbody updated
You can also use actor methods.
Just define new variable like is_in_orbit and if its true (in orbit) then rotate otherwise move with a actor classes interpolation methods.
By the way you also have a opinion to use physics since Newton's law of universal gravitation is also physics but it will be complicated and can cause unexpected results in case of more center points (planets as you said) appear.
i am working on an Android app that will recognize a GO board and create a SGF file of it.
i made a version that is able to detect a board and warp the perspective to make it square ( code and example image below) unfortunately it gets a bit harder when adding stones.(image below)
Important things about a average go board:
round black and white stones
black lines on the board
board color ranges from white to light brown and sometimes with a wood grain
stones are placed on intersections of two lines
correct me if i am wrong but i think my current approach is not a good one.
Has somebody a general idea on how i can separate the stones and lines from the rest of the picture?
My code:
Mat input = inputFrame.rgba(); //original image
Mat gray = new Mat(); //grayscale image
//convert image to grayscale
Imgproc.cvtColor( input, gray, Imgproc.COLOR_RGB2GRAY);
//try to improve histogram (more contrast)
equalizeHist(gray, gray);
//blur image
Size s = new Size(5,5);
GaussianBlur(gray, gray, s, 0);
//apply adaptive treshold
adaptiveThreshold( gray, gray, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY,11,2);
//adding secondary treshold, removes a lot of noise
threshold(gray, gray, 0, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);
Some images:
(source: eightytwo.axc.nl)
(source: eightytwo.axc.nl)
EDIT: 05-03-2016
Yay! managed to detect lines stones and color correctly. precondition the picture has to be only the board itself, without any other background visible.
I use houghLinesP (60lines) and houghCircles (17circles), duration on my phone(1th gen Moto G) about 5 seconds.
Detecting board and warp it turns out to be quite a challenge when it has to be working under different angles and lightning conditions.. still working on that
Suggestions for different approaches are still welcome!!
(source: eightytwo.axc.nl)
EDIT: 15-03-2016
i found a nice way to get line intersects with cross type morphological transformations, works amazing when the picture is taken directly above the board unfortunately not while at an angle (see below)
(source: eightytwo.axc.nl)
In my last update i showed line and stone detection with a picture taken from directly above since then i have been working on detecting the board and warping it in a way that my line and stone detection becomes useful.
harris corner detection
I struggled to get the right parameter settings and i am still not sure if they are optimal, can't find much information on how to optimize image before using harris corners. right now it detects to many corners to be useful. though it feels like it could work. (upper line with pictures in example)
Mat corners = new Mat();
Imgproc.cornerHarris(image, corners, 5, 3, 0.03);
Mat mask = new Mat(corners.size(), CvType.CV_8U, new Scalar(1));
Core.MinMaxLocResult maxVal = Core.minMaxLoc(corners);
Core.inRange(corners, new Scalar(maxVal.maxVal * 0.01), new Scalar(maxVal.maxVal), mask);
cross type morphological transformations
works great when picture is taken directly from above, used from an angle or with a rotated board does not work (middle line with pictures in example)
Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);
Imgproc.adaptiveThreshold(image, image, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 11, 2);
int morph_elem = 1; //0: Rect - 1: Cross - 2: Ellipse
int morph_size = 5;
int morph_operator = 0; //0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat
Mat element = getStructuringElement( morph_elem, new Size(2 * morph_size + 1, 2 * morph_size + 1), new Point( morph_size, morph_size ));
morphologyEx(image, image, morph_operator + 2, element);
contour and houghlines
if there are no stones on the outer boardline and light conditions not to harsh it works pretty well. contours are only part of the board quite often(lower line with pictures in example)
Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);
Imgproc.adaptiveThreshold(image, image, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 11, 2);
Mat hierarchy = new Mat();
MatOfPoint biggest = null;
int contourId = 0;
double biggestArea = 0;
double minSize = 2000;
List<MatOfPoint> contours = new ArrayList<>();
findContours(InvertedImage, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
//find biggest
for( int x = 0; x < contours.size() ; x++ ){
double area = Imgproc.contourArea(contours.get(x));
if( area > minSize && area > biggestArea ){
biggestArea = area;
biggest = contours.get(x);
contourId = x;
}
}
providing the right picture all three the methods work but not good enough to be reliable. any thoughts on parameters, image pre-processing, different approaches or anything that might improve the detection are welcome=)
link to picture
EDIT: 31-03-2016
detecting lines and stones is pretty much solved so i will close this question. created a new one for detecting and warping accurately.
anybody interested in my progress: this is my GOSU Snap Alpha channel don't expect to much of it right now!
EDIT: 16-10-2016
Update: i saw some people are still following this question.
I tested some more stuff and started using Tensorflow, my neural network looks promising, you can have a look at it here.
A lot of work has to be done still, my current image dataset is awful and right now i am working on getting a big dataset.
the app works best using a square board with thick lines and decent lightning.
Assuming that you don't want to "force" your end user to take a cleanest pictures (like using an overlay like some of the QR code scanner for example)
Perhaps you could use some morphological transformations with differents kernels :
Opening and closing with a rectangular kernel for the lines
Opening and closing with an ellipse kernel to get the stones (it should be possible to invert the image at some point to get back the white or the black one)
Take a look at http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html (sorry this one is in C++ but I think this is almost the same in Java)
I had try these operations to remove a grid from a Sudoku to avoid noise in cell extraction and it worked like a charm.
Let me know of these informations were usefull for you (this is for sure a very interesting case)
I'm working on same program. I avoid finding lines at all.
First use perspective transform to get the board into a square as you have done. Find the edges of the 19x19 grid. Then assuming the board is 19x19 you can just compute the position of the lines. This works well for me. Then you compute the closest intersection of the center of the stone to determine which row and col line the stone is on. Works pretty well for me. Only probably is calibrating program for different lighting conditions and different color stones and boards.
I have created below hexagon structure in Andengine with Box2D physics engine. I want to rotate whole structure with respect to center when other ball collides with the structure using physics.
find reference image here : reference question
I tried weld joint and revolute joint with the bodies but it is not performing proper motion as required. All bodies are attached with weld joint and vertices have revolute joint with center body which is static like,
RevoluteJointDef revoluteJointDef1 = new RevoluteJointDef();
revoluteJointDef1.initialize(centerB, movingBody[i], centerB.getWorldCenter());
revoluteJointDef1.enableMotor = true;
revoluteJointDef1.motorSpeed = 0;
revoluteJointDef1.maxMotorTorque = 1f;
this.mPhysicsWorld.createJoint(revoluteJointDef1);
Is there any other way to perform smooth rotation of whole structure?
Thanks.
Oh! i got solution by myself... I did the same thing as i mentioned in first comment my question where I attached balls on a big circle body like,
Body circleBody ... ;// having large radius
//for all balls arranged in hexagon structure
foreach BallBody b
{
WeldJointDef def = new WeldJointDef();
def.initialize(b, circleBody, b.getWorldCenter());
mPhysicsWorld.createJoint(def);
}
and got the rotation by having revolute joint of circleBody with center. Thanks who put their efforts.
I want to ask a basic question just to make sure. When we use Vector2 class for representing some vector in andengine like when we use in joint creation as:
jointDef.localAnchorA.set(new Vector2(1, 1));
Do the values passed i.e. 1, 1 represent 1 meter each?
A little more explanation. Suppose I have created two bodies as:
Rectangle rect1 = new Rectangle(10, 10, 100, 100, vertexBufferObjectManager);
Body body1 = PhysicsFactory.createBoxBody(mPhysicsWorld, rect1, BodyType.DynamicBody, FIXTURE_DEF);
Rectangle rect2 = new Rectangle(110, 110, 50, 50, vertexBufferObjectManager);
Body body2 = PhysicsFactory.createBoxBody(mPhysicsWorld, rect2, BodyType.DynamicBody, FIXTURE_DEF);
And want to create a revolute joint at the position shown in the image below:
So what values for vectors localAnchorpointA and localAnchorPointB should I set to place the upper right corner of red rectangle touching the center of white rectangle? Like:
jointDef.localAnchorA.set(new Vector2(?, ?));
jointDef.localAnchorB.set(new Vector2(?, ?));
This would be very helpful in understanding the usage of vector2 class.
You need to understand what does a Vector2 class represent and stands for in game development. It basically encapsulates the provided coordinates in the 2D space. Taking it a step further, it has numerous applications for which it can be used, from distance calculations to other basic algebraic calculations. Stiegart Blog will give you a much clear idea about Vector2 in android. Hope it clarifies the confusion and misunderstanding.
The Vector2 has no associated units, you decide what the coordinates space looks like on the screen, when you render it (by choosing an appropriate camera). For angels You have to use radians.
But as I can see, You are passing it to the Box2D physics engine. It is recommanded to use units close to m/kg/s. Making your character 2m high would be a good choice. Making your spaceship Enterprise 10km across in Your asteroids game would be too much.
More information can be found in this post: http://box2d.org/2011/12/pixels/ .