Triangle Drawing not repeating for recursion code - java

I am writing a recursion code for my triangle drawing. For some reason, it wont do the recursion, but it will do the base drawing. Would like some help in figuring out why my code isn't repeating. Also, if someone could help me figure out how to fill the triangles with a color, that would be much appreciated.
public class Triangle {
public static void draw(int n, double size, double x, double y) {
if (n == 0) return;
StdDraw.setPenColor(StdDraw.BLUE);
StdDraw.setPenColor(StdDraw.BLACK);
//StdDraw.line(xy, size/2)
double x1 = x + size/2;
double y1 = y + size/2;
double x2 = x1+ size/2;
// bottom triangle
StdDraw.line(x,y, x1, y1);
StdDraw.line(x1, y1, x2, y );
StdDraw.line(x2, y, x1, y);
//right triangle
StdDraw.line(y, y, x2, x2);
StdDraw.line(x1, x1, x1, y1);
// top triangle and left triangle
StdDraw.line(y1, x1, x, x2);
StdDraw.line(x2, x2, x, y);
draw(n-1, size -3, x, y);
}
public static void main(String[] args) {
double x = 0.0;
double y = 0.0;
double size = 1.0;
int n = 2;
draw(n, size, x, y);
}
}

Related

DDA algorithm for all quadrants

i was wondering how can I edit this DDA.
When I have this values: (x1 = 150,y1 = 20,x2 = 100,y2 = 80) it works perfectly fine, because it is in first quadrant.
But if I want to rasterize line from another qudrant
for example with value of (x1 = 10,y1 = 20,x2 = 100,y2 = 80)
this will make just straight line
So I'm having trouble with editing this algorithm to all 4 quadrants.
public void rasterize(int x1, int y1, int x2, int y2, int color) {
int x, y, krok;
float dy, dx;
dx = x2 - x1;
dy = y2 - y1;
if(Math.abs(dx)>Math.abs(dy)){
krok=(int)(Math.abs(dx));
} else {
krok=(int)(Math.abs(dy));
}
dx = dx / (float)krok;
dy = dy/ (float)krok;
x=x1;
y=y1;
for(int i=1;i<=krok;i++){
raster.setPixel(x, y, 0xffff00);
x+=dx;
y+=dy;
}
}

Java Coding areaCircle

I have an assignment for school where I have to create a program that will calculate the area of a circle given four points, but when I invoke the method areaCircle in main, nothing happens. It doesn't calculate the area.
public static void main(String[] args) {
Scanner reader;
reader = new Scanner(System.in);
System.out.println("Enter the coordinates of a point on the outside of a circle.");
System.out.println("x-coordinate: ");
int x1 = reader.nextInt();
System.out.println("y-coordinate: ");
int y1 = reader.nextInt();
System.out.println("Enter the center point of the circle.");
System.out.println("x-coordinate: ");
int x2 = reader.nextInt();
System.out.println("y-coordinate:");
int y2 = reader.nextInt();
areaCircle(x1, y1, x2, y2);
}
public static double distance(int x1, int y1, int x2, int y2) {
double dx = x2 - x1;
double dy = y2 - y1;
double dsquared = dx * dx + dy * dy;
double result = Math.sqrt(dsquared);
return result;
}
public static double areaCircle(int radius, double area) {
area = Math.PI * (radius * radius);
return area;
}
public static double areaCircle(int x1, int x2, int y1, int y2) {
double radius = distance(x1, y1, x2, y2);
double area = Math.PI * (radius * radius);
return area;
}
You need only to print the result, at the moment you are only calculating it.
Instead of
areaCircle (x1, y1, x2, y2);
write
System.out.println("The area is: " + areaCircle (x1, y1, x2, y2));

Filling triangles without fillpolygon?

So I've written a program that compiles, but it won't do what I want it do. It supposed to fill a triangle without using fill polygon. I'm trying to keep the code restricted to loops.
The point is to make the three lines smaller and smaller to fill every part of the triangle.
The way to solve this is, I think would be to figure out where the loop should stop. I took a guess at half the height of the triangle (140).
import javax.swing.*;
import java.awt.*;
public class Tri extends JApplet
{
int x1=0;
int y1 = 140;
int x2 = 120;
int y2 = 140;
int x3 = 60;
int y3;
public void paint (Graphics page)
{
for (y3= 0; y3<=70; y3++)
{
page.drawLine (x1, y1, x2, y2);
page.drawLine (x2, y2, x3, y3);
page.drawLine (x3, y3, x1, y1);
y1++;
x2--;
y2--;
x1++;
}
}
}
change your loop logic, try the following code
int x1=0;
int y1 = 140;
int x2 = 120;
int y2 = 140;
int x3 = 60;
int y3=0;
public void paint (Graphics page)
{
page.drawLine (x1, y1, x2, y2);
page.drawLine (x2, y2, x3, y3);
page.drawLine (x3, y3, x1, y1);
for (x1= 0; x1<=120; x1++)
{
page.drawLine (x3, y3, x1, y1);
} }
keep two lines constant and alter the position of other line by changing its coordinates
for information regarding paint() and repaint follow the link
paint() and repaint() in Java
`

Check program debug

So I finished up a program that recursively draws lines which takes an argument "n" to define the depth of the recursion. I have 2 functions, one which draws the relatively left line and another which draws the relatively right one. I tested it ant it seems to work for the first 4 levels, but then either the lines become too small to accurately represent or there's something wrong with my code because the breaks between the lines seem to become arbitrary. Was hoping somebody could test my code and see if they could find what the problem is.
The following image is of depth 10.
EDIT: fixed a part of code, still need help though
public class Art
{
//draws the relatively left line
public static void drawLeftLine(double x0, double y0, double x1, double y1)
{
//define new x coordinate for line
//double x2 = (1/3.0)*(x1 - x0);
//color of line
StdDraw.setPenColor(StdDraw.BLUE);
//draw line by adding new x coord to original
StdDraw.line(x0, y0, x1, y1);
}
//draw relatively right line
public static void drawRightLine(double x0, double y0, double x1, double y1)
{
//define new x coord for line
//double x2 = (2/3.0)*(x1 - x0);
//color of line
StdDraw.setPenColor(StdDraw.BLUE);
//draw line by adding new x coord to original
StdDraw.line(x0, y0, x1, y1);
}
public static void cantor(int n, double x0, double y0, double x1, double y1)
{
if (n == 0)
return;
drawLeftLine(x0, y0, x1, y1);
drawRightLine(x0, y0, x1, y1);
y0 = y0 - 0.1;
y1 = y1 - 0.1;
cantor(n-1, x0, y0, x0 + ((x1 - x0))/3.0, y1); //left
cantor(n-1, (2.0/ 3) * (x1 - x0) + x0, y0, x1, y1); //right
}
public static void main(String[] args)
{
//change n into integer (depth)
int n = Integer.parseInt(args[0]);
//specify inital values for line
double x0 = 0;
double y0 = 0.9;
double x1 = 0.9;
double y1 = 0.9;
//recursive function cantor
cantor(n, x0, y0, x1, y1);
}
}
I think that the drawing looks incorrect because the of the fact that all of the nice double values are being approximated with discrete pixels causing unwanted overlap between the line segments (see EDIT at the bottom). Some comments about your code however :
1) You don't need the drawLeftLine and drawRightLine methods since currently they are drawing exactly the same thing. Since at each step you are calling cantor twice (once for each side of the deleted inner third), you have one call to cantor for each line segment that has to be drawn. As such I would put all of the drawing directly into the cantor method.
2) Since y0 and y1 are both always the same, I would reduce them to just a single y variable.
3) I would simplify the math for computing the new x0 and x1 values down to
double third = (x1 - x0) / 3;
cantor(n - 1, x0, x0 + third, y); // left
cantor(n - 1, x1 - third, x1, y); // right
4) Instead of decrementing the y value by 0.1 every time, you should have a global variable that decides the amount by which this should be decremented (otherwise if you try n > 10 things will break). This value can just be set to 1.0 / n.
5) You don't need to set the color of the pen every time you paint. You can set it just once in the main method.
6) StdDraw already sets a border around the picture you are drawing so there is no need to start your coordinates from 0.9 - you can use 1 instead.
Following these suggestions the code would look like this :
private static double yIncrement;
public static void cantor(int n, double x0, double x1, double y) {
if (n == 0)
return;
StdDraw.line(x0, y, x1, y);
y = y - yIncrement;
double third = (x1 - x0) / 3;
cantor(n - 1, x0, x0 + third, y); // left
cantor(n - 1, x1 - third, x1, y); // right
}
public static void main(String[] args) {
//change n into integer (depth)
int n = Integer.parseInt(args[0]);
// specify inital values for line
double x0 = 0;
double x1 = 1;
double y = 1;
yIncrement = 1.0 / n;
StdDraw.setPenColor(Color.BLUE);
// recursive function cantor
cantor(n, x0, x1, y);
}
EDIT : Playing around with the StdDraw canvas size, canvas scaling settings, and line segment endpoint rounding mode you can get a slightly better picture (the code below produces a picture that looks mostly correct down to the 8th level)
private static double yIncrement;
public static void cantor(int n, double x0, double x1, double y) {
if (n == 0)
return;
x0 = Math.ceil(x0);
x1 = Math.floor(x1);
StdDraw.line(x0, y, x1, y);
y = y - yIncrement;
double third = (x1 - x0) / 3;
cantor(n - 1, x0, x0 + third, y); // left
cantor(n - 1, x1 - third, x1, y); // right
}
public static void main(String[] args) {
// change n into integer (depth)
int n = Integer.parseInt(args[0]);
int width = 1920;
int height = 1080;
StdDraw.setCanvasSize(width, height);
// specify inital values for line
double x0 = 0;
double x1 = width;
double y = 1;
yIncrement = 1.0 / n;
StdDraw.setPenColor(Color.BLUE);
StdDraw.setXscale(0, width);
// recursive function cantor
cantor(n, x0, x1, y);
}
To display everything down to the tenth level with absolute correctness you would need a width of 3^9 pixels (19K pixels). For level 9 that's 3^8 = 6K. For level 8 that's 3^7 = 2k, which is why it looks almost correct with 1.9K pixel width and integer rounding.

Recursive Sierpinski's Triangle Java

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

Categories

Resources