Chaos game android - java

I am currently developing a "chaos game" for android. For those that don't know what it is: you pick some random numbers, and according to a given set of rules a dot is drawn somewhere on a canvas; after many iterations you get a shape, always the same.
In this case, it is a fern.
here is my code:
MainActivity.java
public class MainActivity extends Activity {
DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawView = new DrawView(this);
setContentView(drawView);
}
}
DrawView.java
public class DrawView extends View{
int viewWidth;
int viewHeight;
int iterations = 10000; // how many dots
int myColor;
Paint paint = new Paint();
Random rand = new Random();
public DrawView(Context context) {
super(context);
myColor = context.getResources().getColor(com.*****.******.*****.R.color.ferncolor); //Green
paint.setColor(myColor);
paint.setAntiAlias(true);
}
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
#Override
public void onDraw(Canvas canvas) {
Double x = rand.nextDouble();
Double y = rand.nextDouble();
Double random;
for(int i = 0; i < iterations; i++){
random = rand.nextDouble();
if(random < 0.01){
x = 0.0;
y *= 0.16;
}
else if(random < 0.86){
x = (0.85 * x) + (0.04 * y);
y = (-0.04 * x) + (0.85 * y) + 1.6;
}
else if(random < 0.93){
x = (0.2 * x) - (0.26 * y);
y = (0.23 * x) + (0.22 * y) + 1.6;
}
else{
x = (-0.15 * x) + (0.28 * y);
y = (0.26 * x) + (0.24 * y) + 0.44;
}
Double posx = viewWidth/2.0 + x*viewWidth/7.5;
Double posy = y*viewHeight/10.2;
canvas.drawCircle(posx.floatValue(), posy.floatValue(), (float) 0.5, paint); //drawing dot at (posx,posy), size 0.5, with custom paint
}
}
}
My problem is that you have to wait for all the point to be drawn before you can see the view. That often leads to several awkward seconds blankness. What I would like is a "refresh" after every iteration (or every x iterations, depending on how much iterations I have).
I think that could be achieved via threading but I have no idea on how to achieve that.
Any ideas?
Thank you!

You can force a view to redraw by calling its invalidate() method. So you can try putting that at the end of your for loop.
More information here.
Also, invalidating too often could cause a performace slowdown, so if you want to draw 10000 dots, you could probably call invalidate only on every 500th iteration or something...

Related

Trying to do a simple Jump

I'm trying to learn how to make a 2D Game without Game Engines, anyways I already created a background scrolling right now my goal is to make my character jump. But the thing is whenever I start my app the character is spinning up and down and it will just go away to the background.
Here's my character code
public class Deer extends GameCharacter {
private Bitmap spritesheet;
private double dya;
private boolean playing;
private long startTime;
private boolean Jump;
private Animate Animation = new Animate();
public Deer(Bitmap res, int w, int h, int numFrames) {
x = 20;
y = 400;
dy = 0;
height = h;
width = w;
Bitmap[] image = new Bitmap[numFrames];
spritesheet = res;
for (int i = 0; i < image.length; i++)
{
image[i] = Bitmap.createBitmap(spritesheet, i*width, 0, width, height);
}
Animation.setFrames(image);
Animation.setDelay(10);
startTime = System.nanoTime();
}
public void setJump(boolean b){
Jump = b;
}
public void update()
{
long elapsed = (System.nanoTime()-startTime)/1000000;
if(elapsed>100)
{
}
Animation.update();
if(Jump){
dy = (int)(dya+=5.5);
}
else{
dy = (int)(dya+=5.5);
}
if(dy>14)dy = 14;
if(dy>14)dy = -14;
y += dy*2;
dy = 0;
}
public void draw(Canvas canvas)
{
canvas.drawBitmap(Animation.getImage(),x,y,null);
}
public boolean getPlaying(){return playing;}
public void setPlaying(boolean b){playing = b;}
public void resetDYA(){dya = 0;}
}
x - character's horizontal position
y - character's vertical position
dx - character's horizontal acceleration
dy - character's vertical acceleration
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN) {
if(!deer.getPlaying()) {
deer.setPlaying(true);
}
deer.setJump(true);
return true;
}
return super.onTouchEvent(event);
}
I can't say for sure if this is the only problem because you have other suspicious code but it looks like you jump no matter what.
if(Jump){
dy = (int)(dya+=5.5);
} else {
dy = (int)(dya+=5.5);
}
If Jump is true you set the vertical acceleration. But you also set the vertical acceleration to the same value if Jump is false. You also don't show in your code where Jump is ever set to false.
Another odd bit of code is:
if(dy>14)dy = 14;
if(dy>14)dy = -14;
Here, if dy>14 you set it to 14. Then you check dy>14 immediately after. Of course, this time it's false. But because those two conditions are the same the second one will never pass since the one before it ensures it won't. The only other option is they both fail. IOW, you'll never be able to enter the second if.
All that aside, I'm not sure why you're taking this approach. You can simply rely on physics equations with constant acceleration, give an initial velocity, check for a collision with the ground (or at least the original height), and just let it run. For example:
// These are the variables you need.
int x = 200, y0 = 0, y = 0, velocity = 15;
double t = 0.0, gravity = -9.8;
// This is the statement that should run when you update the GUI.
// It is the fundamental equation for motion with constant acceleration.
// The acceleration is the gravitational constant.
y = (int) (y0 + velocity * t + .5 * gravity * t * t);
if (y < 0) {
y = y0 = 0;
//Stop jumping!
Jump = false;
} else {
// Swap the y values.
y0 = y;
// Increase the time with the frame rate.
t += frameRate;
}
// Draw the character using the y value
The best part about this is you don't need to worry about when you get to the maximum height because the equation will automatically bring you down. It also looks more natural as if the mechanics are real. Try it out.
A simple Swing example that you can play around with. Note that the values are different to deal with the way the components are drawn to the screen. Normally, you would deal with that with transformations but this will do for the task.
public class Main {
static Timer timer;
Main() {
JFrame frame = new JFrame("Hello sample");
frame.setSize(new Dimension(550, 550));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel panel = new MyPanel();
frame.add(panel);
frame.setVisible(true);
timer = new Timer(5, (e) -> panel.repaint());
timer.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Main::new);
}
class MyPanel extends JPanel {
int x = 200, y0 = 300, y = 0, w = 200, h = 200, v = -8;
double t = 0.0, gravity = 9.8;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
y = (int) (y0 + v * t + .5 * gravity * t * t);
if (y > 300) {
y = y0 = 300;
// To prevent it from stopping comment the timer.stop() and
// uncomment the t = 0.0 statements.
//t = 0.0;
timer.stop();
} else {
y0 = y;
t += .025;
}
g.drawOval(x, y, w, h);
}
}
}

Java how to make a circle slowly move around?

Hello I have an app where there are circles floating around. At the moment the don't float around, which is the problem. I want them to slowly move around in random directions. How can I do this?
Here is my circle class:
public class data {
public int x,y, size,id;
public data(int x,int y){
this.x = x;
this.y = y;
size = new Random().nextInt(50);
id = new Random().nextInt(10);
}
public void tick(){
}
public void render(Graphics g){
g.setColor(new Color(38,127,0));
g.fillOval(x, y, size, size);
g.setColor(Color.black);
g.drawOval(x, y, size, size);
}
}
You can have a very random movement by adding a random value to x and to y every tick:
private Random random = new Random();
public void tick() {
x = x + random.nextFloat();
y = y + random.nextFloat();
}
This will result in a very fuzzy motion.
Another option is to have 2 variables: motionX and motionY. Those get added to x and y every tick, after which you add random values to motionX and motionY:
private Random random = new Random();
private float xMotion = 0f, yMotion = 0f;
private float factor = 0.5f; //just a value to reduce speed
private void tick() {
x = x + xMotion;
y = y + yMotion;
xMotion = xMotion + random.nextFloat() * factor;
yMotion = yMotion + random.nextFloat() * factor;
}
First of all, I think you messed up which one you should random, you random selected a size and the id(what is this for anyways?), not the x,y value. Also, I don't know why, but it seems that the render program must be called paint.

Nesting issue in Processing

I'm having an issue with the animation I'm making. The principal idea is that 6 equilateral triangles revolve around a central point, while also rotating about their own selves.
When I run the code, each instance of a triangle uses the previous instance as a reference point, rather than the centre. This causes a cool spiral effect, but it's not what I'm after.
Code follows:
//Declare
tri myTri1;
tri myTri2;
tri myTri3;
tri myTri4;
tri myTri5;
tri myTri6;
void setup() {
size(600, 600);
smooth();
//Initialise
myTri1 = new tri();
myTri2 = new tri();
myTri3 = new tri();
myTri4 = new tri();
myTri5 = new tri();
myTri6 = new tri();
}
void draw() {
background(0);
//Call Functions
myTri1.run();
translate(width/2,height/2);
rotate(PI/3);
translate(-width/2,-height/2);
myTri2.run();
translate(width/2,height/2);
rotate(PI/3);
translate(-width/2,-height/2);
myTri3.run();
translate(width/2,height/2);
rotate(PI/3);
translate(-width/2,-height/2);
myTri4.run();
translate(width/2,height/2);
rotate(PI/3);
translate(-width/2,-height/2);
myTri5.run();
translate(width/2,height/2);
rotate(PI/3);
translate(-width/2,-height/2);
myTri6.run();
}
Second tab:
class tri {
//Variables
float ax, ay, bx, by, cx, cy; //triangle point coordinates
float theta; //triangle angle
float pi = PI; //pi reference
//Construct
tri() {
theta = PI/6;
ax = 0;
ay = 0;
bx = -50*(sin(theta));
by = +50*(cos(theta));
cx = +50*(sin(theta));
cy = +50*(cos(theta));
}
//Functions
void run() {
translate(width/2, height/2);
revolve(); //revolve triangle about centre
spin(); //spin triangle about itself
pulse(); //move triangle in/out
display(); //show triangle
translate(-width/2, -height/2);
}
void spin() {
translate(0, by/2); //sets rotation axis to centre of triangle
rotate(millis()*-0.0005*pi);
translate(0, -by/2); //resets axis to centre of window
}
void revolve() {
translate(-2*by, 0);
ax = ax + 2*sin(millis()*0.005);
ay = ay + 4*cos(millis()*0.005);
bx = bx + 2*sin(millis()*0.005);
by = by + 4*cos(millis()*0.005);
cx = cx + 2*sin(millis()*0.005);
cy = cy + 4*cos(millis()*0.005);
translate(2*by, 0);
}
void pulse() {
ay = ay + 5*sin(millis()*0.005);
by = by + 5*sin(millis()*0.005);
cy = cy + 5*sin(millis()*0.005);
}
void display() {
fill(255);
strokeWeight(0.8);
triangle(ax, ay, bx, by, cx, cy);
}
}
If anyone can point out where I'm going wrong with this it would be awesome, and if you can suggest any optimisations RE the formation of the hexagon (instead of the mess of translations) I would be incredibly happy.
Franchesca's suggestion good. You should have an idea of where the origin is and how the coordinate space transformations you apply affect that, at least until you get a feel for it and you're in complete control.
I also warmly recommend this Processing tutorial on 2d transformations
Now, back to your code :)
First thing you can improve is getting used to for loops and arrays.
They may look scary at first, but once you get the hang of them they're quite easy.
Wherever you can think of a situation where repetition is needed, you can use a for loop to make your life easier.
In your case, generating the triangles and storing them can be done using loops and arrays.
For loop have the following syntax:
for keyword (3 elements: a start point,an end point(condition) and an increment,(separated by the ; character)
Let's say you want to move from a(0) to b(10) one step at a time:
for(int currentPos = 0 ; currentPos < 10; currentPos++){
println("step: " + currentPos);
}
If you can walk, you can also skip :)
for(int currentPos = 0 ; currentPos < 10; currentPos+=2){
println("step: " + currentPos);
}
even backwards if you want:
for(int currentPos = 10 ; currentPos > 0; currentPos--){
println("step: " + currentPos);
}
This is very useful when traversing all sort of data(triangles in a scene, vertices in a triangle, etc.)
How do you organize your data ? You place it in a list or array.
An array contains elements of the same type and has a set length.
The syntax to declare an array is like so:
ObjectType[] nameOfArray;
and you can initialize an empty array:
int[] fiveNumbers = new int[5];//new keyword then the data type and length in sq.brackets
or you can initialize the array with values:
String[] words = {"ini","mini","miny","moe"};
You access elements in an array using square brackets and the index of the object in the list you want to access. Arrays have a length property so you can easily count objects.
background(255);
String[] words = {"ini","mini","miny","moe"};
for(int i = 0 ; i < words.length; i++){
fill(map(i,0,words.length, 0,255));
text(words[i],10,10*(i+1));
}
Now back to your original question.
Here is your main code simplified using for loops and arrays:
//Declare
int numTri = 6;//number of triangles
tri[] triangles = new tri[numTri];//a list/an array of tri objects (currently empty)
float angleIncrement = TWO_PI/numTri;
float radius = 100;
void setup() {
size(600, 600);
smooth();
//Initialise
for(int i = 0 ; i < numTri; i++){
triangles[i] = new tri();//allocate/initialise each tri object into it's 'slot' in the list/array
}
}
void draw() {
background(0);
translate(width * .5, height * .5);//move everything to the centre
for(int i = 0 ; i < numTri; i++){
pushMatrix();
rotate(angleIncrement * i);//rotate from the last offset(centre)
translate(radius,0);//move on (rotated) X axis away from the centre
triangles[i].run();
popMatrix();
}
}
void drawAxes(int size){
pushStyle();
stroke(255,0,0);
line(0,0,size,0);
stroke(0,255,0);
line(0,0,0,size);
popStyle();
}
Notice I've indented the code within push/pop matrix calls.
It's not necessary but I've added that so you can get a feel for how coordinate spaces nest.
These call are very useful as they deal with the nitty gritty math part behind the scenes for you. Notice how I'm placing the symbols in a circle without using the polar to cartesian conversion formula (cos(angle) * radius, sin(angle) * radius).
You can test that with this code from your other tab:
class tri {
//Variables
float ax, ay, bx, by, cx, cy; //triangle point coordinates
float theta; //triangle angle
float pi = PI; //pi reference
//Construct
tri() {
theta = PI/6;
ax = 0;
ay = 0;
bx = -50*(sin(theta));
by = +50*(cos(theta));
cx = +50*(sin(theta));
cy = +50*(cos(theta));
}
//Functions
void run() {
pushMatrix();
revolve(); //revolve triangle about centre
// pulse(); //move triangle in/out
display(); //show triangle
popMatrix();
}
void revolve() {
translate(-2*by, 0);
float angle = millis()*0.005;
float cos = cos(angle);
float sin = sin(angle);
ax = ax + 2*sin;
ay = ay + 4*cos;
bx = bx + 2*sin;
by = by + 4*cos;
cx = cx + 2*sin;
cy = cy + 4*cos;
translate(2*by, 0);
}
void pulse() {
ay = ay + 5*sin(millis()*0.005);
by = by + 5*sin(millis()*0.005);
cy = cy + 5*sin(millis()*0.005);
}
void display() {
fill(255);
strokeWeight(0.8);
triangle(ax, ay, bx, by, cx, cy);
}
}
Also notice I've added a drawAxes function. That's just a utility to make it easier to understand in what coordinate space your drawing.
Again, going back to arrays and for loops, here's a modified version of your code:
class tri {
//Variables
float ai = TWO_PI/3;//angle increment
float r = 50;
float sr = r * 1.5;//spin radius
float vt = 5;//vertical translation(for pulse)
PVector[] verts = new PVector[3];
boolean rotateAroundCentre = true;
boolean translateAroundCentre = false;
boolean translateVertically = false;
//Construct
tri() {
for(int i = 0 ; i < 3; i++){
verts[i] = new PVector(cos(ai * i) * r,sin(ai * i) * r);
}
}
//Functions
void run() {
pushMatrix();
float angle = millis()*0.0005;
if(rotateAroundCentre) rotate(angle);
if(translateVertically) translate(sin(angle)*vt,0);
if(translateAroundCentre){
// translate(cos(angle) * sr,sin(angle) * r);
// or
rotate(angle);
translate(sr,0);
}
display(); //show triangle
popMatrix();
}
void display() {
fill(255);
strokeWeight(0.8);
triangle(verts[0].x, verts[0].y, verts[1].x, verts[1].y, verts[2].x, verts[2].y);
drawAxes(10);
}
}
Feel free to play with the boolean rotateAroundCentre,translateAroundCentre,translateVertically variables and have fun playing with coordinates and geometry :)
For example here's a version of the sketch that you can toggle the 3 options above using the 1/2/3 keys on your keyboard:
//Declare
int numTri = 6;//number of triangles
tri[] triangles = new tri[numTri];//a list/an array of tri objects (currently empty)
float angleIncrement = TWO_PI/numTri;
float radius = 100;
boolean[] options = {false,false,false};
void setup() {
size(600, 600);
smooth();
//Initialise
for(int i = 0 ; i < numTri; i++){
triangles[i] = new tri();//allocate/initialise each tri object into it's 'slot' in the list/array
}
}
void draw() {
background(0);
translate(width * .5, height * .5);//move everything to the centre
for(int i = 0 ; i < numTri; i++){
pushMatrix();
rotate(angleIncrement * i);//rotate from the last offset(centre)
translate(radius,0);//move on (rotated) X axis away from the centre
drawAxes(20);
triangles[i].run();
popMatrix();
}
}
void drawAxes(int size){
pushStyle();
stroke(255,0,0);
line(0,0,size,0);
stroke(0,255,0);
line(0,0,0,size);
popStyle();
}
void keyReleased(){
for(int i = 0 ; i < 3; i++) if(key == (49+i)) options[i] = !options[i];//quick'n'dirty option toggling
for(int i = 0; i < numTri; i++) {
triangles[i].rotateAroundCentre = options[0];
triangles[i].translateAroundCentre = options[1];
triangles[i].translateVertically = options[2];
}
}
class tri {
//Variables
float ai = TWO_PI/3;//angle increment
float r = 50;
float sr = r * 1.5;//spin radius
float vt = 5;//vertical translation(for pulse)
PVector[] verts = new PVector[3];
boolean rotateAroundCentre = false;
boolean translateAroundCentre = false;
boolean translateVertically = false;
//Construct
tri() {
for(int i = 0 ; i < 3; i++){
verts[i] = new PVector(cos(ai * i) * r,sin(ai * i) * r);
}
}
//Functions
void run() {
pushMatrix();
float angle = millis()*0.0005;
if(rotateAroundCentre) rotate(angle);
drawAxes(30);
if(translateVertically) translate(sin(angle)*vt,0);
drawAxes(40);
if(translateAroundCentre){
// translate(cos(angle) * sr,sin(angle) * r);
// or
rotate(angle);
drawAxes(40);
translate(sr,0);
}
display(); //show triangle
popMatrix();
}
void display() {
fill(255);
strokeWeight(0.8);
triangle(verts[0].x, verts[0].y, verts[1].x, verts[1].y, verts[2].x, verts[2].y);
drawAxes(10);
}
}

moving an object in a circle - android

I posted this question yesterday, I got some useful help but was unable to solve the problem. Just figured I'd keep trying.
Ok. I'm trying to make a ball move in a circle on a canvas in Android. After doing some research and reading a few similar questions - I think I got the logic down but the shape remains stationary. Basically I'm doing x = a +rcos(theta), y = rain(theta). I'm not really sure what the problem is. My code is below. Does anyone know what I'm doing wrong? I've read the other questions and don't know why I can't make it work.
public class DrawingTheBall extends View {
Bitmap bball;
int x,y, theta;
public DrawingTheBall(Context context) {
super(context);
// TODO Auto-generated constructor stub
bball = BitmapFactory.decodeResource(getResources(), R.drawable.blueball);
x = 0;
y = 0;
theta = 45;
}
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Rect ourRect = new Rect();
ourRect.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
float a = 10;
float b = 10;
float r = 20;
theta = (int) Math.toRadians(10);
Paint blue = new Paint();
blue.setColor(Color.BLUE);
blue.setStyle(Paint.Style.FILL);
canvas.drawRect(ourRect, blue);
if(x < canvas.getWidth()){
x = (int) (a +r*Math.cos(theta));
}else{
x = 0;
}
if(y < canvas.getHeight()){
y = (int) (b +r*Math.sin(theta));
}else{
y = 0;
}
Paint p = new Paint();
canvas.drawBitmap(bball, x, y, p);
invalidate();
}
}
You have to increment theta on the line:
theta = (int) Math.toRadians(10);
If you always draw at the same angle, you'll always draw to the same location.
EDIT:
You could place the above line in your constructor, and then in onDraw, you could do:
theta = (theta + 0.1) % (2 * Math.PI)

Circular Movement Image in JAVA

I want an circular movement of an image in JAVA, i thought I have the solution but it doesn't work and i'm a bit clueless now.
For calculating the points it needs to go im using pythagoras to calculate the height (point B).
if it does one round im satisfied but more rounds would be cool.
The image size is around 500 x 300 pixels.
Here's my code :
package vogel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
public class Vogel extends Component {
private int x;
private int r;
private int b;
BufferedImage img;
public vogel() {
try {
img = ImageIO.read(new File("F:/JAVA/workspace/School/src/vogel/vogel.png"));
} catch (IOException e) {
}
r = 60;
x = 10;
}
#Override
public void paint(Graphics g) {
for(int i = -x; i <= x; i++) {
b = (int)Math.sqrt(r^2 - i^2);
g.drawImage(img, x, b, this);
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Vogel");
f.setSize(1000,1000);
f.add(new Vogel());
f.setVisible(true);
for (int number = 1; number <= 1500000; number++) {
f.repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {}
}
}
}
Using your loop in the paint(Graphics) method, it draws 21 birds with one repaint.
You should do it with an angle stored in an object variable and use the Math.sin() and Math.cos() function calculate the x and y position. The angle should be increased with every repaint().
To add:
// To control the radius of moving
private final double MAX_X = 200;
private final double MAX_Y = 200;
private double angle = 0;
#Override
public void paint(Graphics g) {
// increase angle (should be a double value)
angle += 0.1;
// rotate around P(0/0), assuming that 0° is vector (1/0)
int x = (int) (Math.cos(angle) * MAX_X);
int y = (int) (Math.sin(angle) * MAX_Y);
// move P to center of JFrame (width and height = 1000)
x += 500;
y += 500;
// image is 500x300, calc upper left corner
x -= 250;
y -= 150;
// draw
g.drawImage(img, x, y, null);
}
To remove:
private double x, b, r;
So this is the code, try it.
Addition to Sibbo's code to convert angle to rads
private double angle = 0.1;
#Override
public void paint(Graphics g) {
// increase angle (should be a double value
double random = angle * 2.0 * Math.PI/360.0; //this will convert it to rads
// rotate around P(0/0)
int x = (int) (Math.cos(random) * MAX_X);
int y = (int) (Math.sin(random) * MAX_Y);
// move P to center of JFrame (width and height = 1000)
x += 500;
y += 500;
// image is 500x300, calc upper left corner
x -= 250;
y -= 150;
angle++
// draw
g.drawImage(img, x, y, null);
}

Categories

Resources