I am trying to create a jigsaw puzzle demo, and I would like to know of alternative ways of creating puzzle pieces without using mask. Currently I have jigsaw pieces by taking a full image, breaking that image up into four pieces (lets say the puzzle is 2x2) and then storing and applying a mask to each piece. It looks like the below
// create standard puzzle pieces
arryPieceEndPos = new int[mCols][mRows];
arryPieceImg = new Bitmap[mCols * mRows];
arryIsPieceLocked = new boolean[mCols * mRows];
int pos = 0;
for (int c = 0; c < mCols; c++) {
for (int r = 0; r < mRows; r++) {
arryPieceImg[pos] = Bitmap.createBitmap(mBitmap,
c * mPieceWidth, r * mPieceHeight,
mPieceWidth, mPieceHeight);
arryIsPieceLocked[pos] = false;
arryPieceEndPos[c][r] = pos;
pos++;
}
}
I then use a helper method to apply a mask to each piece
private Bitmap maskMethod(Bitmap bmpOriginal, Bitmap bmpMask) {
// adjust mask bitmap if size is not the size of the puzzle piece
if (bmpMask.getHeight() != mPieceHeight ||
bmpMask.getWidth() != mPieceWidth) {
Log.e("TEST", "Resize Error :: H (mask): " + bmpMask.getHeight() + " // W (mask): " +
bmpMask.getWidth());
Log.d("TEST", "Resize Error :: H (norm): " + mPieceHeight + " // W (norm): " +
mPieceWidth);
}
Canvas canvas = new Canvas();
Bitmap combine = Bitmap.createBitmap(bmpOriginal.getWidth(), bmpOriginal.getHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(combine);
Paint paint = new Paint();
paint.setFilterBitmap(false);
canvas.drawBitmap(bmpOriginal, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(bmpMask, 0, 0, paint);
paint.setXfermode(null);
return combine;
}
I have been reading up on bezier curves and openGL. Neither of these I am very familiar with and they are very complex. I would like some help with forming a jigsaw puzzle piece, so that I can have an example of how it can be done.
Bezier curves can be complex, but we can "cheat" by defining the puzzle heads using Catmul-Rom curves first (which have the nice property of actually passing through their control points) and then trivially converting them to Bezier curves instead (since they're both plain Hermite splines).
So: let's do this. An example image:
All we've done is split it up so far, using fairly simple rules. In sort-of-code (technically: Processing):
int hx = width/4;
int hy = height/4;
for(int x = hx; x<width; x+=hx) {
line(x,0,x,height);
for(int y = hy; y<height; y+=hy) {
line(0,y,width,y);
}
}
And other than a fun image, it's not very exciting, so let's invent some puzzle joins. First off, we mark the centers of those cuts:
Again not really exciting:
for(int x = hx/2; x<width; x+=hx) {
for(int y = hy/2; y<height; y+=hy) {
ellipse(x + hx/2,y,5,5);
ellipse(x,y + hy/2,5,5);
}
}
But, we can make it exciting. For each of those centers, we can pick points to the left/right or up/down (depending on the edge) and decide whether to have the piece extend to the left or right, and then invent some points "around the center" to give us our Catmull-Rom curve:
for(int x = hx/2; x<width; x+=hx) {
for(int y = hy/2; y<height; y+=hy) {
// horizontal
ellipse(x-5, y+hy/2, 2,2);
ellipse(x+5, y+hy/2, 2,2);
boolean up = random(1) < 0.5;
if(up) {
ellipse(x-random(5,10), y+hy/2 - random(10,20), 2,2);
ellipse(x+random(5,10), y+hy/2 - random(10,20), 2,2);
} else {
ellipse(x-random(5,10), y+hy/2 + random(10,20), 2,2);
ellipse(x+random(5,10), y+hy/2 + random(10,20), 2,2);
}
// vertical
ellipse(x+hx/2, y-5, 2,2);
ellipse(x+hx/2, y+5, 2,2);
boolean left = random(1) < 0.5;
if(left) {
ellipse(x+hx/2-random(10,20), y-random(5,10), 2,2);
ellipse(x+hx/2-random(10,20), y+random(5,10), 2,2);
} else {
ellipse(x+hx/2+random(10,20), y-random(5,10), 2,2);
ellipse(x+hx/2+random(10,20), y+random(5,10), 2,2);
}
}
}
We're over-generating here, so I'll leave it to you to figure out how to prevent the "piece joiner" coordinates from being computed for the right-most and lowest-most edges (which should be fairly easy).
Now then: let's turn this into a coordinate grid, because that's looking pretty good, and we should get pretty nice piece joiners using Catmull-Rom:
Beauty.
for (int x = hx/2; x<width; x+=hx) {
for (int y = hy/2; y<height; y+=hy) {
// horizontal
int xs = x-hx/2,
ym = y+hy/2,
xe = x+hx/2;
float x3, x4, y1, y2,
x1 = x-5,
x2 = x+5;
boolean up = random(1) < 0.5;
x3 = x - random(5, 10);
x4 = x + random(5, 10);
if (up) {
y1 = y+hy/2 - random(10, 20);
y2 = y+hy/2 - random(10, 20);
} else {
y1 = y+hy/2 + random(10, 20);
y2 = y+hy/2 + random(10, 20);
}
curve(xs, ym, x1, ym, x3, y1, x4, y2);
curve(x1, ym, x3, y1, x4, y2, x2, ym);
curve(x3, y1, x4, y2, x2, ym, xe, ym);
// vertical
int ys = y-hy/2,
xm = x+hx/2,
ye = y+hy/2;
y1 = y-5;
y2 = y+5;
float y3, y4;
boolean left = random(1) < 0.5;
y3 = y - random(5, 10);
y4 = y + random(5, 10);
if (left) {
x1 = x+hx/2 - random(10, 20);
x2 = x+hx/2 - random(10, 20);
} else {
x1 = x+hx/2 + random(10, 20);
x2 = x+hx/2 + random(10, 20);
}
curve(xm, ys, xm, y1, x1, y3, x2, y4);
curve(xm, y1, x1, y3, x2, y4, xm, y2);
curve(x1, y3, x2, y4, xm, y2, xm, ye);
}
}
It should be relatively obvious where you need to do perform your cuts to end up with these pieces now, but if you're working with a system that can't do Catmull-Rom but can only do Bezier curves, the conversion is really straight forward. The preceding code's been using
curve(x1,x2,y1,y2,x3,y3,x4,y4);
but that's a Catmull-Rom curve. To get the equivalent curve, we can use a Bezier segment of the form:
bezier(
x2, y2,
x2 - (x3-x1)/6, y2 - (y3-y1)/6,
x3 + (x4-x2)/6, y3 + (y4-y2)/6,
x3, y3
)
And let's get puzzling.
Related
I am trying to draw an arc on Jpanel in swing from user input having the center of arc, starting point and end point of arc.
here is my current
int x1 = 300; //start point
int y1 = 300;
int x2 = 350; //center point of arc
int y2 = 350;
int x3 = 300; //end point of arc
int y3 = 400;
int h1 = y1 - y2; //calculate with and height from start-center and center-end
int d1 = x2 - x1;
int h2 = y2 - y3;
int d2 = x3 - x2;
int startangle = (int)(Math.atan(h1 / d1) * 180 / Math.PI);
if (x2 > x1 && y2 > y1) {
startangle = 180 - startangle;
} else if (x2 < x1) {
//change sign
} else if (y1 < y2) {
//change sign
}
System.out.println("x1,y1\n" + x1 + "\n" + y1 + "\n" + d2 / h2 + "\n" + Math.atan(d2 / h2) * 180 / Math.PI);
int endangle = (int)(Math.atan2(x3, y3) * 180 / Math.PI);
System.out.println("args: " + "\n" + x2 + "\n" + y2 + "\n" + startangle + "\n" + endangle + "\n");
g2.drawArc(x1, y1, d1, h1, startangle, startangle);
g2.drawArc(x2, y2, d2, h2, 0, endangle);
However i am not getting the arc on screen, literally nothing related to it (other shapes work but not this one). No errors or exceptions were thrown.
Edit: Thanks to #MadProgrammer's comment, i am getting a shape but not what i expect.
What i get:
What i expect from the same set of coordinates:
Edit 2: managed to make it work by using a bezier curve instead of an arc
It worked by using a bezier curve and drawing quadcurve in two phases (start-middle,middle-end) using the calculated control points instead of the drawArc method.
I think the bounding rectangle of drawarc is the height and width of the ellipse that your arc is part of.
Is there a way I can test if a Rectangle object collides with a line? Thanks!
EDIT :
public boolean overlapsLineNodes(Vector2 point1, Vector2 point2) {
boolean collide = false;
MapObjects mapObjects = play.getWorld().level.getCurrentLevel().getLayers().get("collidable").getObjects();
Tools.shapeRenderer.setAutoShapeType(true);
Tools.shapeRenderer.setProjectionMatrix(play.getCamera().combined);
Tools.shapeRenderer.begin();
for (RectangleMapObject rectangleObject : mapObjects.getByType(RectangleMapObject.class)) {
rectangle.setX(rectangleObject.getRectangle().x * 1/64f);
rectangle.setY(rectangleObject.getRectangle().y * 1/64f);
rectangle.setWidth(rectangleObject.getRectangle().width * 1/64f);
rectangle.setHeight(rectangleObject.getRectangle().height * 1/64f);
float x1 = rectangle.x, y1 = rectangle.y + rectangle.height,
x2 = rectangle.x + rectangle.width, y2 = rectangle.y + rectangle.height,
x3 = rectangle.x + rectangle.width, y3 = rectangle.y,
x4 = rectangle.x, y4 = rectangle.y;
Vector2 start = point1, end = point2;
float[] floatArray = new float[]{x1, y1, x2, y2, x3, y3, x4, y4};
polygon.setVertices(floatArray);
if (Intersector.intersectLinePolygon(start, end, polygon)) {
Tools.shapeRenderer.setColor(Color.GREEN);
collide = true;
}
Tools.shapeRenderer.line(point1.x, point1.y, point2.x, point2.y);
Tools.shapeRenderer.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
Tools.shapeRenderer.setColor(Color.WHITE);
}
I do this, but it seems not to give me correct results. I am rending all of the rectanglemapobjects in white, and if one collides with the line, then I render it in green. It randomly renders some in green and I cant figure out why.
The problem was that intersectLinePolygon is the wrong method! I should have been using intersectSegmentPolygon.
Compute the intersection of the line with the line defining one edge of the rectangle, determine the whether the intersection point lies between the endpoints of the edge. Repeat with the opposite edge. If you get "yes" to either, they intersect.
You do not need to test all 4 edges; just two opposite edges.
If rectangle edges are parallel to the axis ... [x1,y1]-[x2,y1]-[x2,y2]-[x1,y2] ... and your line in question is y = m*x + b, then this becomes simply:
ya = m*x1 + b;
yb = m*x2 + b;
collision = ((ya < y1) ^ (ya < y2)) || ((yb < y1) ^ (yb < y2));
Or, if you order "ya < yb", you can get more precise over whether just touching a corner is considered a collision:
collision = ((ya <= y1) && (y1 <= yb)) || ((ya <= y2) && (y2 <= yb));
Assuming that you know start and end point of your line and also vertices of rectangle (which you must know to be honest :) ) you can use Intersector's intersectLinePolygon() method just like
//definition of variables - of course you can keep your x... y... in float[] array
float x1 = 0, x2 = 0, x3 = 0, x4 = 0, y1 = 0, y2 = 0, y3 = 0, y4 = 0;
Vector2 start = null, end = null;
//...
//updateing vertices and line start/end points
//...
Intersector.intersectLinePolygon(start, end, new Polygon(new float[]{x1, y1, x2, y2, x3, y3, x4, y4}));
If you are using this in render() method it is not good to create new Polygon() instance every time - better keep one instance somewhere
Polygon p = new Polygon();
and then just update it with vertices just before collision checking
p.setVertices(...);
I am trying to avoid creating circle on another circle. I can not get the collision detection working. The machine crashes with endless loop.
How can I make sure that the circles don`t collide with each other while creating them?
ArrayList balls;
int maxBall = 10;
void setup() {
size(1000, 800);
smooth();
noStroke();
// Create an empty ArrayList
balls = new ArrayList();
float radius = 100;
balls.add(new Ball(random(50, width-50), random(50, height-50), radius, color(0, 255, 100) ));
while (balls.size() < maxBall) {
Ball ball = new Ball(random(50, width-50), random(50, height-50), radius, color(0, 255, 100) );
for (int i = 0; i < balls.size(); i++) {
Ball currentBall = (Ball) balls.get(i);
float distance = checkCollision(currentBall.getX(), currentBall.getY(), radius, ball.getX(), ball.getY(), radius);
if (distance > 200) {
balls.add(ball);
println("Added, distance: " + distance);
}
println();
//println("Distance: " + distance);
}
}
}
void draw() {
background(0, 0);
for (int i = balls.size()-1; i >= 0; i--) {
Ball ball = (Ball) balls.get(i);
ball.display();
}
}
class Ball {
float x;
float y;
float r;
color colorID;
Ball(float tempX, float tempY, float tempW, color tempColor) {
x = tempX;
y = tempY;
r = tempW;
colorID = tempColor;
}
void display()
{
fill (colorID);
ellipse(x, y, r, r);
}
float getX() {
return x;
}
float getY() {
return y;
}
}
float checkCollision(float x1, float y1, float r1, float x2, float y2, float r2) {
return dist(x1, y1, r1, x2, y2, r2);
}
Your code doesn't make a ton of sense. First you loop through the ArrayList and check whether any of them collide. If not, you add another Ball, but you don't check whether that new Ball collides with anything already in the ArrayList.
Instead, you have to check whether the new Ball intersects anything already in the ArrayList. Something like this:
while (maxBall > balls.size()) {
Ball ball = new Ball(random(50, width-50), random(50, height-50), 100, color(0, 255, 100) );
boolean foundCollision = false;
for (Ball currentBall : balls) {
isColliding = checkcirclecollide(currentBall.getX(), currentBall.getY(), 100, ball.getX(), ball.getY(), 100);
if(isColliding){
foundCollision = true;
}
}
if(!foundCollision){
balls.add(ball);
}
}
Also, just use the dist() function that comes with Processing:
boolean checkcirclecollide(double x1, double y1, float r1, double x2, double y2, float r2) {
return dist(x1, y1, x2, y2) < (r1 + r2);
}
More info can be found in the Processing reference.
I managed to get it working. This might be useful for some body, so I will explain what I have done.
The first problem was the ellipseMode, I set it to:
ellipseMode(RADIUS);
Secondly, I wasn`t aware of dist function
dist(x1, y1, r1, x2, y2, r2);
Anyway, the working code:
ArrayList balls;
int maxBall = 10;
boolean foundCollision;
void setup() {
size(1000, 800);
smooth();
noStroke();
ellipseMode(RADIUS);
// Create an empty ArrayList
balls = new ArrayList();
float radius = 100;
balls.add(new Ball(random(100, width-100), random(100, height-100), radius, color(0, 255, 100) ));
int counter = 0;
while (balls.size() < maxBall) {
foundCollision = false;
Ball ball = new Ball(random(100, width-100), random(100, height-100), radius, color(0, 255, 100) );
for (int i = 0; i < balls.size(); i++) {
Ball currentBall = (Ball) balls.get(i);
float distance = checkCollision(currentBall.getX(), currentBall.getY(), radius, ball.getX(), ball.getY(), radius);
if (distance < 200) {
foundCollision = true;
counter = counter+1;
println("COllision: " + counter);
break;
}
distance = 0;
}
if (!foundCollision) {
balls.add(ball);
}
}
println("Total COllision counter: " + counter);
}
void draw() {
background(0, 0);
for (int i = balls.size()-1; i >= 0; i--) {
Ball ball = (Ball) balls.get(i);
ball.display();
}
}
class Ball {
float x;
float y;
float r;
color colorID;
Ball(float tempX, float tempY, float tempW, color tempColor) {
x = tempX;
y = tempY;
r = tempW;
colorID = tempColor;
}
void display()
{
fill (colorID);
ellipseMode(RADIUS);
ellipse(x, y, r, r);
}
float getX() {
return x;
}
float getY() {
return y;
}
}
// Check the collision
float checkCollision(float x1, float y1, float r1, float x2, float y2, float r2) {
return dist(x1, y1, r1, x2, y2, r2);
}
I'm trying to draw Sierpinski's Triangle recursively in Java, but it doesn't work, though to me the logic seems fine. The base case is when the triangles are within 2 pixels of each other, hence the use of the Distance Formula.
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.Canvas;
public class Triangle extends Canvas implements Runnable
{
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
public Triangle()
{
setBackground(Color.WHITE);
}
public void paint( Graphics window )
{
window.setColor(Color.BLUE);
window.setFont(new Font("ARIAL",Font.BOLD,24));
window.drawString("Serpinski's Gasket", 25, 50);
triangle(window, (WIDTH-10)/2, 20, WIDTH-40, HEIGHT-20, 40, HEIGHT-20, 4);
}
public void triangle(Graphics window, int x1, int y1, int x2, int y2, int x3, int y3, int r)
{
//if statement base case
//midpoint = (x1 + x2 / 2), (y1 + y2/ 2)
if(Math.sqrt((double)(Math.pow(x2-x1, 2)) + (double)(Math.pow(y2-y1, 2))) > 2)
//if(r==0)
{
window.drawLine(x1, y1, x2, y2);
window.drawLine(x2, y2, x3, y3);
window.drawLine(x3, y3, x1, y1);
}
int xa, ya, xb, yb, xc, yc; // make 3 new triangles by connecting the midpoints of
xa = (x1 + x2) / 2; //. the previous triangle
ya = (y1 + y2) / 2;
xb = (x1 + x3) / 2;
yb = (y1 + y3) / 2;
xc = (x2 + x3) / 2;
yc = (y2 + y3) / 2;
triangle(window, x1, y1, xa, ya, xb, yb, r-1); // recursively call the function using the 3 triangles
triangle(window, xa, ya, x2, y2, xc, yc, r-1);
triangle(window, xb, yb, xc, yc, x3, y3, r-1);
}
public void run()
{
try{
Thread.currentThread().sleep(3);
}
catch(Exception e)
{
}
}
}
The Runner is
import javax.swing.JFrame;
public class FractalRunner extends JFrame
{
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
public FractalRunner()
{
super("Fractal Runner");
setSize(WIDTH+40,HEIGHT+40);
getContentPane().add(new Triangle());
setVisible(true);
}
public static void main( String args[] )
{
FractalRunner run = new FractalRunner();
}
}
To me this should work but it causes a runtime/StackOverFlow error that I don't know how to correct. Any help?
You need to move the recursive calls to triangle, and the associated math, inside the conditional check on the separation. Right now, it will always call it and therefore you get the stack overflow.
Chances are your base case might not be working properly- what if the distance between two triangles is never two pixels? say we star with y1 and x1 being 0 and 200. their midpoint would be 100, then 50, 25, 12, 6, 3, 1<--- never hits the 2 pixel base case...
"StdDraw" was taken from here:
public class Sierpinski {
public static void sierpinski(int n) {
sierpinski(n, 0, 0, 1);
}
public static void sierpinski(int n, double x, double y, double size) {
if (n == 0) return;
//compute triangle points
double x0 = x;
double y0 = y;
double x1 = x0 + size;
double y1 = y0;
double x2 = x0 + size / 2;
double y2 = y0 + (Math.sqrt(3)) * size / 2;
// draw the triangle
StdDraw.line(x0, y0, x1, y1);
StdDraw.line(x0, y0, x2, y2);
StdDraw.line(x1, y1, x2, y2);
StdDraw.show(100);
//recursive calls
sierpinski(n-1, x0, y0, size / 2);
sierpinski(n-1, (x0 + x1) / 2, (y0 + y1) / 2, size / 2);
sierpinski(n-1, (x0 + x2) / 2, (y0 + y2) / 2, size / 2);
}
// read in a command-line argument n and plot an order Sierpinski Triangle
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
StdDraw.setPenRadius(0.005);
sierpinski(n);
}
}
Guy
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I need to draw a fractal swirl using the algorithm Iterated Function System.
There are coefficients for this fractal:
0.745455 -0.459091 0.406061 0.887121 1.460279 0.691072 0.912675
-0.424242 -0.065152 -0.175758 -0.218182 3.809567 6.741476 0.087325
And here is my code:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Surface extends JPanel {
double a1 = 0.745455;
double b1 = -0.459091;
double d1 = 0.406061;
double e1 = 0.887121;
double c1 = 1.460279;
double f1 = 0.691072;
double p1 = 0.912675;
double a2 = -0.424242;
double b2 = -0.065152;
double d2 = -0.175758;
double e2 = -0.218182;
double c2 = 3.809567;
double f2 = 6.741476;
double p2 = 0.087325;
double x1(double x, double y) {
return a1 * x + b1 * y + c1;
}
double y1(double x, double y) {
return d1 * x + e1 * y + f1;
}
double x2(double x, double y) {
return a2 * x + b2 * y + c2;
}
double y2(double x, double y) {
return d2 * x + e2 * y + f2;
}
public void paint(Graphics g) {
drawFractal(g);
}
void drawFractal(Graphics g) {
double x1 = 300;
double y1 = 300;
double x2 = 0;
double y2 = 0;
g.fillOval(300 + (int) x1, 300 + (int) y1, 3, 3);
for (int i = 0; i < 10000; i++) {
double p = Math.random();
if (p < 0.91675) {
x2 = x1(x1, y1);
y2 = y1(x1, y1);
g.fillOval(300 + (int) x2, 300 + (int) y2, 3, 3);
x1 = x2;
y1 = y2;
} else {
x2 = x2(x1, y1);
y2 = y2(x1, y1);
g.fillOval(300 + (int) x2, 300 + (int) y2, 3, 3);
x1 = x2;
y1 = y2;
}
}
}
}
Unfortunately, with this code I get a wrong picture:
It would be great if someone could point out my mistake.
Your generation seems correct (i.e. don't do x1 = x2 +300; y1 = y2 +300;), but your problem is you're way off the scale for the purposes of rendering. This means there are very few points that fall outside very center of the image.
Your window is [0..600]x[0..600]. Try multiplying x2 and y2 with 50, so that you're rendering the [-6..6]x[-6..6] region instead of the [-300..300]x[-300..300] region of space.
Note that it should be sufficient to draw single pixels (as lines to itself) instead of 3x3 ovals.
int xp = 300 + (int) (x2 * scale);
int yp = 300 + (int) (y2 * scale);
g.drawLine(xp, yp, xp, yp);
Depending on what gets rendered, you might need to adjust the scale slightly to get the entire image with reasonable bounds. Note the second transformation offsets by -6.7, so a scale of 30 should be about right.
Also note that by using x1 = x2 +300; y1 = y2 +300; you change the transformations and get a different fractal (at a scale at which you expect).
This is great, I was wrong thinking that exponential runtime required! The fractals appeared more dimensional than my imagination!
Thanks #Jan Dvorak!
The following also works (in my coordinates, xcenter=300, ycenter=100 and radius=50 are global drawing parameters) and works faster:
void drawFractal2(Graphics g) {
double x1 = 0;
double y1 = 0;
double x2 = 0;
double y2 = 0;
double p;
g.fillOval(xcenter + (int) (x1 * radius), ycenter + (int) (y1 * radius), 3, 3);
for(int i=0; i<100000; ++i) {
p = Math.random();
if (p < p1) {
x2 = x1(x1, y1);
y2 = y1(x1, y1);
}
else {
x2 = x2(x1, y1);
y2 = y2(x1, y1);
}
g.fillOval(xcenter + (int) (x2 * radius), ycenter + (int) (y2 * radius), 3, 3);
x1 = x2;
y1 = y2;
}
}
and the picture is better
BELOW IS MY INCORRECT ANSWER
But it show how fractals are bigger than the intuition, so I keep it.
I guess your algorithm should be tree-like (recursive) while your one is linear. You are just drawing one chain of points, transforming it one after one. So you get some spiral-like chain. It can't generate any fractal picture in principle.
I GOT YOUR PICTURE
You have 2 mistakes:
1) you pass 300 both into iteration and as drawing shift. This is minor.
2) You algorithm is linear. Linear algorithm can't draw tree-like picture. If you use random values, you should run algorithm multiple times. One chain draws only one random portion of the picture.
I got your picture with following recursive algorithm. It works slow but you are to improve it.
void drawFractal(Graphics g, double x1, double y1, int depth) {
double x2 = 0;
double y2 = 0;
if( depth > 20 ) {
return;
}
g.fillOval(xcenter + (int) (x1 * radius), ycenter + (int) (y1 * radius), 3, 3);
x2 = x1(x1, y1);
y2 = y1(x1, y1);
drawFractal(g, x2, y2, depth+1);
x2 = x2(x1, y1);
y2 = y2(x1, y1);
drawFractal(g, x2, y2, depth+1);
}
to run it I used
public void paint(Graphics g) {
//drawFractal(g);
drawFractal(g, 0, 0, 0);
}
parameters are
int xcenter = 300;
int ycenter = 100;
int radius = 50;
the picture is follows: