Montecarlo method and JFrame (math and java problem) - java

I made a little program to approximate Pi and I would like to represent it. I started but I thought it would look better if the points outside the circle were red and the ones inside were green. I can't do it and I don't understand why the problem is there. I don't know if it is in pure math or in dev.
for(int i = 0; i<1000; i++) {
double x = Math.random() * (500-250) + 250;
double y = Math.random() * 250;
double applyformula = (x - 250)*(x - 250) + (y - 250) * (y - 250);
if(applyformula == y || (y*y) - 500 * y < applyformula ) {
g.fillOval((int) x,(int) y, 5, 5);
g.setColor(Color.GREEN);
} else {
g.fillOval((int) x,(int) y, 5, 5);
g.setColor(Color.RED);
}
}
If someone could help me, that will be perfect.

It could be done in a simpler way.
for (int i = 0; i < 1000; i++) {
double x = Math.random();
double y = Math.random();
double applyformula = (x * x) + (y * y);
if (applyformula <= 1) {
g.setColor(Color.GREEN);
} else {
g.setColor(Color.RED);
}
// Set the actual coordinates in a 250 pixels wide square.
x *= 250;
y *= 250;
g.fillOval((int) x, (int) y, 5, 5);
}

Related

Glitching when running program in parallel

I have a problem in regards to parallelism in javafx. More specifically, dividing the canvas of my program to run with multiple threads. When compiled, the program glitches out and doesn't work as supposed to. The code in the thread class is supposed to print out the Mandelbrot set, and the code in the application class is dividing the canvas into different parts that each should run in parallel. Here is the code:
public void MandelbrotSet(int n) {
int widthh = (int)canvas.getWidth();
int portion = widthh / n;
for (int i = 0; i < n; i++) {
int startX = i * portion;
int endX = startX + portion;
myMandelbrotParallelTEST2 thread = new myMandelbrotParallelTEST2(startX, endX, image, width, height, maximumIterations, canvas, zoom, xPos, yPos, hue, brightness, saturation, R, G, B);
thread.start();
//would add thread.join() here with try and catch
}
canvas.getGraphicsContext2D().drawImage(image, 0, 0);
}
this is how the code in the Thread class looks:
#Override
public void run(){
double centerY = canvas.getWidth() / 2.0;
double centerX = canvas.getHeight() / 2.0;
for (int x = start; x < end; x++) {
for (int y = 0; y < canvas.getHeight(); y++) {
double cr = xPos / width + (x - centerY) / zoom;
double ci = yPos / height + (y - centerX) / zoom; //getting position of the points on the canvas
int iterationsOfZ = 0;
double zr = 0.0;
double zi = 0.0;
while (iterationsOfZ < maximumIterations && (zr * zr) + (zi * zi) < 4) {
double oldZr = zr;
zr = (zr * zr) - (zi * zi) + cr;
zi = 2 * (oldZr * zi) + ci;
iterationsOfZ++;
}
int iterations = iterationsOfZ;
if (iterations == maximumIterations) { //inside the set
imagee.getPixelWriter().setColor(x, y, Color.rgb(R, G, B));
} else if (brightness == 0.9) { //white background
imagee.getPixelWriter().setColor(x, y, Color.hsb(hue, iterations / maximumIterations, brightness));
} else if (hue == 300) { //colorful background
imagee.getPixelWriter().setColor(x, y, Color.hsb(hue * iterations / maximumIterations, saturation, brightness));
} else if (hue == 0 && saturation == 0 && brightness == 1) {
imagee.getPixelWriter().setColor(x, y, Color.hsb(hue, saturation, brightness));
} else { //black background
imagee.getPixelWriter().setColor(x, y, Color.hsb(hue, saturation, iterations / brightness));
}
}
}
//canvas.getGraphicsContext2D().drawImage(imagee, 0, 0);
}
[this is how the program looks, and while panning around it glitches even more, but the execution time is really fast, which means that it is ran concurrently.]enter code here(https://i.stack.imgur.com/IZUfY.png)
I found that adding thread.join() fixes the problem, but then the program is ran on a single thread. Could anyone help me out resolve this issue?
What you are trying to do cannot be done with a Canvas because of the fx application thread restiction which has already been mentioned.
But it can be done via the WritableImage of JavaFX 13+ with support for Buffers. Writing into the buffer is not restricted in the above way and can thus be done in parallel with high performance.
I have compiled some examples (not any parallel ones) of how to use WritableImages with Buffers here: https://github.com/mipastgt/JFXToolsAndDemos

How to repaint a specific area (e.g. circle) in java?

I am trying to make a simple game where you basically have to hit the circles to get a point. But i faced a tiny problem which i couldn't really solve on my own so here is my question how do I repaint a round surface.I used the repaint(Rectangle r) method but it doesn't workout.
public void objectHit(MouseEvent e) {
int distance = 0, deltaX = 0, deltaY = 0, RadiusSqaured = 0;
for (int i = 0; i < obj.length; i++) {
deltaX = e.getX() - obj[i].getPoint().x;
deltaY = e.getY() - obj[i].getPoint().y;
distance = deltaX * deltaX + deltaY * deltaY;
RadiusSqaured = obj[i].getRadius() * obj[i].getRadius();
if (distance <= RadiusSqaured) {
repaint(obj[i].repaintRect());
x = ThreadLocalRandom.current().nextInt(50 + radius / 2, 850 - radius / 2);
y = ThreadLocalRandom.current().nextInt(60 + radius / 2, 750 - radius / 2);
repaint(obj[i].repaintRect());
}
}
}
In JComponent, there is a method for repainting based on a box area. Does this satisfy your requirements?
https://docs.oracle.com/javase/8/docs/api/javax/swing/JComponent.html#repaint-long-int-int-int-int-

2D Collision Detection LWJGL

I'm new to LWJGL and need help with collision detection. Below I have included the two java classes that I am working with. The Ship.java class draws a square and then you can move the square around. The Enemy.java displays red square.
I would like to have the ship collide with the enemy. I am confused on what to do.
Ship.java
package WallWars;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.input.Keyboard;
public class Ship {
double x;
double y;
double spdX;
double spdY;
double directionLeft;
Enemy enemy = new Enemy();
public Ship(){
x = 100;
y = 100;
}
public void ShipLogic(){
x += spdX;
y += spdY;
//Friction
if(!Keyboard.isKeyDown(Keyboard.KEY_LEFT) && spdX > 0){
spdX = spdX * 0.9;
}
if(!Keyboard.isKeyDown(Keyboard.KEY_RIGHT) && spdX < 0){
spdX = spdX * 0.9;
}
if(!Keyboard.isKeyDown(Keyboard.KEY_UP) && spdY < 0){
spdY = spdY * 0.85;
}
if(!Keyboard.isKeyDown(Keyboard.KEY_DOWN) && spdY > 0){
spdY = spdY * 0.85;
}
//Keyboard Input
if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)){
spdX = Math.max(-5, spdX - 1);
}
if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)){
spdX = Math.min(5, spdX + 1);
}
if(Keyboard.isKeyDown(Keyboard.KEY_UP)){
spdY = Math.max(4.5, spdY + 1);
}
if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)){
spdY = Math.min(-4.5, spdY - 1);
}
}
public void ShipCollisions(){
//Wall Collisions
if(x <= 0){
spdX = 0;
x = 0.1;
}
if(x >= 768){
spdX = 0;
x = 767.9;
}
if(y <= 0){
spdY = 0;
y = 0.1;
}
if(y >= 568){
spdY = 0;
y = 567.9;
}
}
public void EnemyCollisions(){
if(x > enemy.x + 60 + 32 && x < enemy.x){
}
}
public void dShip(){
ShipLogic();
ShipCollisions();
EnemyCollisions();
glBegin(GL_QUADS);
glColor3d(1, 1, 1);
glVertex2d(x, y);
glVertex2d(x + 32, y);
glVertex2d(x + 32, y + 32);
glVertex2d(x, y + 32);
glEnd();
}
}
Enemy.java
package WallWars;
import static org.lwjgl.opengl.GL11.*;
public class Enemy {
double x;
double y;
double posX = x;
double posY = y;
public void dEnemy(double x, double y){
glBegin(GL_QUADS);
glColor3d(1, 0, 0);
glVertex2d(x, y);
glVertex2d(x + 32, y);
glVertex2d(x + 32, y + 32);
glVertex2d(x, y + 32);
glEnd();
}
}
First of all you can use the Rectangle class of the Java API.
It can store a position (x, y) and a width and a height.
Once all your objects (your ship and your enemy) use Rectangle, you can simply use the intersects method to know if two Rectangle collide.
The problem you're facing is that you need to encapsulate your behaviour (logic) methods in a "run" (infinite) loop.
Then, in your main loop if you detect a collision (the simple part) you need to do something about it. The first thing you can do is to stop moving your ship. Later you can try to avoid the obstacle by taking another path.

Get all pixels between two pixels

Im writing a small painting programm in java, and im stucked on the pen:
Therory: When im dragging the mouse i have to fill the circles between P(draggedX|draggedY) and P2(mouseX|mouseY) with circles. So i have to create a line / a path (?..) and calculate all points that are on it.
What ive tried:
double m = 0;
int width = draggedX - mouseX;
int height = draggedY - mouseY;
if(draggedX - mouseX != 0){
m = (draggedY - mouseY) / (draggedX - mouseX);
}
if(width > 0){
for(int i = 0; i < width; i++) {
double x = mouseX + i;
double y = mouseY + (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else if(width < 0){
for(int i = -width; i > 0; i--) {
double x = mouseX + i;
double y = mouseY + (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else{
if(height > 0){
for(int i = 0; i < height; i++){
g.fillOval(mouseX, (int) i + mouseY, 5, 5);
}
}
else if(height < 0){
for(int i = -height; i > 0; i--){
g.fillOval(mouseX, (int) i + mouseY, 5, 5);
}
}
}
It didnt work correct. sometimes curious lines splashed up and circles werent painted, like this:
Any other ideas, how to solve it?
Thank you!
Java will not generate events for all intermediate points - you can test this by drawing a point at each place where you actually receive an event. If the mouse moves too quickly, you will miss points. This happens in all drawing programs.
Bresenham's line-drawing algorithm is the traditional way to find integer pixels between two pixels coordinates. But you are programming in Java, and you have something much better: you can trace arbitrary paths, defined through coordinates. Two flavors are available,
The old Graphics version (g is a Graphics, possibly from your paintComponent() method):
// uses current g.setColor(color)
g.drawPolyline(xPoints, yPoints, int nPoints); // xPoints and yPoints are integer arrays
And the new Shape-based version (g2d is a Graphics2D; your Graphics in Swing can be cast to Graphics2D without problems):
// uses current stroke
g2d.draw(p); // p is a Path2D, build with successive moveTo(point) and lineTo(point)
I recommend the second version, since the stroke offers a lot more flexibility (line width, dashes, ...) than just simple colors
The division between two integers discards the fractional part: for example 2/3 returns 0. You can use floating point types for computation to keep the fractional parts.
double m;
m = (double) (draggedY - mouseY) / (draggedX - mouseX);
In addition to what the other answer said, you also need to do your drawing differently if the absolute value of m is greater than 1 or not. If it's 1 or less, then you'll want to iterate along the x direction and calculate the y from the slope. Otherwise, you'll need to iterate along the y direction and calculate the m from the (inverse) slope. You have the right idea in the code, but it's not quite implemented correctly. It should be something more like this:
if (abs(m) <= 1)
{
for (int i = startX; i < endX; i++)
{
float y = startY + (float)i * m;
float x = i;
g.fillOval(x, y, 5, 5);
}
}
else
{
for (int i = startY; i < endY; i++)
{
float x = startX + (float)i / m;
float y = i;
g.fillOval(x, y, 5, 5);
}
}

Drawing Program Bug

im programing a small drawing program.
But i have a bug with painting. left, right, does work correct, but top, bottom creates curious images. why? ANyone a idea? Im programming in java.
The Bug: (left normal, right bug) And no it ISNT because mouseevent isnt getting all points. Im drawing all circles between to points i actually get. see the code.
The code for painting:
double m = 0;
int width = draggedX - mouseX;
int height = draggedY - mouseY;
if(draggedX - mouseX != 0){
m = (double) (draggedY - mouseY) / (double) (draggedX - mouseX);
}
if(width > 0){
for(int i = 0; i < width; i++) {
double x = mouseX + i;
double y = mouseY + (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else if(width < 0){
for(int i = -width; i > 0; i--) {
double x = mouseX - i;
double y = mouseY - (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else{
if(height > 0){
for(int i = 0; i < height; i++){
g.fillOval(mouseX, (int) i + mouseY, 5, 5);
}
}
else if(height < 0){
for(int i = -height; i > 0; i--){
g.fillOval(mouseX, (int) i - mouseY, 5, 5);
}
}
else{
g.fillOval(mouseX, mouseY, 5, 5);
}
}
Mouse events are tricky, they don't always follow a linear progression. Instead of using oval, I would simple paint lines between each distinct event point. If you need to make the lines thicker, the take a look at Stroke (or BasicStroke in particular)
For example Resize the panel without revalidation
I also have a very bad feeling your a painting directly to the graphics context by using getGraphics instead of using paintComponent
Suppose you draw a nearly vertical line with width = 10 and height = 200. With the given loop you will draw exactly 10 points, which is not enough to cover the entire line.
To fix this you need to check if height > width and in that case plot the points "vertically," iterating along the y-axis.
// when height > width
for(int i = 0; i < height; i++) {
double x = mouseX + i/m;
double y = mouseY + i;
g.fillOval((int) x, (int) y, 5, 5);
}
As you can see the algorithm to plot a single line becomes quite complex. That's why Bresenham's algorithm is such a big deal.

Categories