drawing squares using a recursive method with java - java

I am trying to write an applet that draws a main square and then uses a recursive method that draws smaller squares on the corners of the main square. I'm really confused on how to go about this. I have drawn the square with the others squares on its corners but i need to do this process recursively and thats where i get lost. I need to set a min side length so the recursive method knows when to stop. Here is my code.
import javax.swing.JApplet;
import java.awt.*;
public class LabC extends JApplet
{
public void paint(Graphics g)
{
g.drawRect(50, 100, 100, 100);
g.drawRect(25, 75, 50, 50);
g.drawRect(125, 75, 50, 50);
g.drawRect(125, 175, 50, 50);
g.drawRect(25, 175, 50, 50);
}
}

I think this is more or less what are you looking for
public static class LabC extends JLabel {
public void paintRecursiveWraper(Graphics g, int minW, int minH, int x, int y, int w, int h) {
g.drawRect(x, y, w, h);
paintRecusive(g, minW, minH, x, y, w, h);
}
public void paintRecusive(Graphics g, int minW, int minH, int x, int y, int w, int h) {
if (h <= minH || w <= minW) {
return;
}
int newW, newH;
int newX, newY;
newW = (int) (w * scaleFactor);
newH = (int) (h * scaleFactor);
// Bot Left Square
newX = x;
newY = y;
g.drawRect(newX, newY, newW, newH);
paintRecusive(g, minW, minH, newX, newY, newW, newH);
// Bot Right Square
newX = (int) (x + w * (1 - scaleFactor));
newY = y;
g.drawRect(newX, newY, newW, newH);
paintRecusive(g, minW, minH, newX, newY, newW, newH);
// Top Left Square
newX = x;
newY = (int) (y + h * (1 - scaleFactor));
g.drawRect(newX, newY, newW, newH);
paintRecusive(g, minW, minH, newX, newY, newW, newH);
// Top Right Square
newX = (int) (x + w * (1 - scaleFactor));
newY = (int) (y + h * (1 - scaleFactor));
g.drawRect(newX, newY, newW, newH);
paintRecusive(g, minW, minH, newX, newY, newW, newH);
}
public void paint(Graphics g) {
paintRecursiveWraper(g, 10, 10, 0, 0, 1000, 1000);
}
}
scaleFactor has to be between 0 and 1
Edited*

Related

Java: Rotate Rectangle

I am trying to rotate a Rectangle from the vertices closest to the origin, but it is placing it way off the frame.
I have the following class:
class MyRectangle {
MyRectangle(int x, int y, int w, int h, int a){
xPos = x;
yPos = y;
width = w;
height = h;
angle = a;
}
public int xPos;
public int yPos;
public int width;
public int height;
public int angle;
public void paintComponent(Graphics g) {
g.drawRect(xPos, yPos, width, height);
Rectangle rect2 = new Rectangle(xPos, yPos, width, height);
Graphics2D gg = (Graphics2D) g.create();
AffineTransform transform = new AffineTransform();
transform.rotate(angle, rect2.getX() + rect2.width/2, rect2.getY() + rect2.height/2);
AffineTransform old = gg.getTransform();
gg.transform(transform);
gg.rotate(Math.toDegrees(-angle));
gg.draw(rect2);
}
}
I am caling the rectangle with:
MyRectangle rect = new MyRectangle(10, 200, 30, 50, 70);
It is showing up like this:
I included the original un-rotated rectangle. It should rotate from the bottom left vertex.

How to interlock shapes in Java

I have a project where I have to draw Olympic Rings and I am having trouble making it seem like the ring interlock. This is a picture that shows what I mean.
notice how they interlock? That's what I want right now I only have the shapes sitting on top of each other. This is what I have right now.
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Color; //sets color
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.AlphaComposite;
class ColoredOlypmicRings extends JFrame {
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
float strokeThickness = 27.0f;
float arcThickness = 9.0f;
BasicStroke Outline = new BasicStroke(strokeThickness);
BasicStroke arcOutline = new BasicStroke(arcThickness);
g2d.setStroke(Outline);
g2d.setColor(Color.blue);
g2d.drawOval(100, 100, 300, 300);
g2d.setColor(Color.yellow);
g2d.drawOval(265, 300, 300, 300);
g2d.setColor(Color.black);
g2d.drawOval(430, 100, 300, 300);
g2d.setColor(Color.green);
g2d.drawOval(595, 300, 300, 300);
g2d.setColor(Color.red);
g2d.drawOval(760, 100, 300, 300);
g2d.setStroke(arcOutline);
g2d.setColor(Color.white);
g2d.drawArc(253, 378, 50, 75, -230, 58); // -270 start
g2d.drawArc(290, 370, 50, 75, -230, 58);
g2d.drawArc(360, 285, 50, 75, -230, 58);
g2d.drawArc(405, 285, 50, 75, -230, 58);
}
public ColoredOlypmicRings() {
setSize(1200, 800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
ColoredOlypmicRings guiWindow = new ColoredOlypmicRings();
guiWindow.setVisible(true);
}
}
Draw arcs of colors that when combined form your circles rather than drawing whole ovals.
The top layer of arcs need to be drawn last. This may take a little trial and error, but you can do this.
General recommendation to never draw in a top level window such as a JFrame.
Instead draw within a JPanel's paintComponent method, and then display that JPanel within your JFrame
Always call the super's painting method in your overridden method.
Smooth your drawing by using Graphics2D setRenderingHints and turn anti-aliasing on.
First iteration -- not yet fully fixed:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import javax.swing.*;
#SuppressWarnings("serial")
public class OlympicRings extends JPanel {
private static final Color BG = Color.WHITE;
private static final int OVAL_WIDTH = 300;
private static final int OVAL_HEIGHT = OVAL_WIDTH;
private static final int X_START = 100;
private static final int Y_START = X_START;
private static final int DELTA_X = 175;
private static final int DELTA_Y = 180;
private static final Color COLOR_GOLD = new Color(242, 205, 25);
private static final Stroke INNER_STROKE = new BasicStroke(30f);
private static final Stroke OUTER_STROKE = new BasicStroke(40f);
private static final int ARC_LENGTH = 30;
private static final int CIRCLE_DEGREES = 360;
public OlympicRings() {
setBackground(BG);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int x = X_START;
int y = Y_START;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH);
x += DELTA_X;
y += DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH);
x += DELTA_X;
y -= DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH);
x += DELTA_X;
y += DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH);
x += DELTA_X;
y -= DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.RED, OVAL_WIDTH);
x = X_START;
y = Y_START;
int angle = CIRCLE_DEGREES - ARC_LENGTH;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH, angle, ARC_LENGTH);
x += DELTA_X;
y += DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH, 0, ARC_LENGTH);
x += DELTA_X;
y -= DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH, angle, ARC_LENGTH);
x += DELTA_X;
y += DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH, 0, ARC_LENGTH);
g2.dispose();
}
private void myDrawArc(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
Color bg2, Color color, int ovalWidth, int start, int end) {
g2.setStroke(outerStroke);
g2.setColor(bg2);
g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);
g2.setStroke(innerStroke);
g2.setColor(color);
g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);
}
private void myDrawOval(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
Color bg2, Color color, int ovalWidth) {
g2.setStroke(outerStroke);
g2.setColor(bg2);
g2.drawOval(x, y, ovalWidth, ovalWidth);
g2.setStroke(innerStroke);
g2.setColor(color);
g2.drawOval(x, y, ovalWidth, ovalWidth);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
int w = 2 * X_START + DELTA_X * 4 + OVAL_WIDTH;
int h = 2 * Y_START + DELTA_Y + OVAL_HEIGHT;
return new Dimension(w, h);
}
private static void createAndShowGui() {
OlympicRings mainPanel = new OlympicRings();
JFrame frame = new JFrame("OlympicRings");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
This is not quite there as my background stroke extends beyond the end of the arc:
still working on it.
Slightly better:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import javax.swing.*;
#SuppressWarnings("serial")
public class OlympicRings extends JPanel {
private static final Color BG = Color.WHITE;
private static final int OVAL_WIDTH = 300;
private static final int OVAL_HEIGHT = OVAL_WIDTH;
private static final int X_START = 100;
private static final int Y_START = X_START;
private static final int DELTA_X = 175;
private static final int DELTA_Y = 180;
private static final Color COLOR_GOLD = new Color(242, 205, 25);
private static final Stroke INNER_STROKE = new BasicStroke(30f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND);
private static final Stroke OUTER_STROKE = new BasicStroke(40f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
private static final int ARC_LENGTH = 30;
private static final int CIRCLE_DEGREES = 360;
public OlympicRings() {
setBackground(BG);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int x = X_START;
int y = Y_START;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH);
x += DELTA_X;
y += DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH);
x += DELTA_X;
y -= DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH);
x += DELTA_X;
y += DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH);
x += DELTA_X;
y -= DELTA_Y;
myDrawOval(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.RED, OVAL_WIDTH);
x = X_START;
y = Y_START;
int angle = CIRCLE_DEGREES - ARC_LENGTH;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH, angle, ARC_LENGTH);
x += DELTA_X;
y += DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH, 0, ARC_LENGTH);
x += DELTA_X;
y -= DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH, angle, ARC_LENGTH);
x += DELTA_X;
y += DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH, 0, ARC_LENGTH);
g2.dispose();
}
private void myDrawArc(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
Color bg2, Color color, int ovalWidth, int start, int end) {
g2.setStroke(outerStroke);
g2.setColor(bg2);
g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);
g2.setStroke(innerStroke);
g2.setColor(color);
g2.drawArc(x, y, ovalWidth, ovalWidth, start, end);
}
private void myDrawOval(Graphics2D g2, Stroke innerStroke, Stroke outerStroke, int x, int y,
Color bg2, Color color, int ovalWidth) {
g2.setStroke(outerStroke);
g2.setColor(bg2);
g2.drawOval(x, y, ovalWidth, ovalWidth);
g2.setStroke(innerStroke);
g2.setColor(color);
g2.drawOval(x, y, ovalWidth, ovalWidth);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
int w = 2 * X_START + DELTA_X * 4 + OVAL_WIDTH;
int h = 2 * Y_START + DELTA_Y + OVAL_HEIGHT;
return new Dimension(w, h);
}
private static void createAndShowGui() {
OlympicRings mainPanel = new OlympicRings();
JFrame frame = new JFrame("OlympicRings");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
Latest change:
x = X_START;
y = Y_START;
int angle = CIRCLE_DEGREES - ARC_LENGTH;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLUE, OVAL_WIDTH, angle, ARC_LENGTH);
x += DELTA_X;
y += DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, COLOR_GOLD, OVAL_WIDTH, 57, ARC_LENGTH);
x += DELTA_X;
y -= DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.BLACK, OVAL_WIDTH, angle, ARC_LENGTH);
x += DELTA_X;
y += DELTA_Y;
myDrawArc(g2, INNER_STROKE, OUTER_STROKE, x, y, BG, Color.GREEN.darker(), OVAL_WIDTH, 57, ARC_LENGTH);
and the result:
This is the output of the code that the OP posted:
White border around rings - instead of attempting to hard-code the border only when rings cross each other, you should draw a white arc before you draw any color arc, with the white arc having a broader stroke than the colored one.
Overlaps - if you draw all rings one after the other, you will have to fix at least 4 overlaps so that it looks like the logo you're after. You should repaint each of those 4 overlaps (blue-over-yellow, yellow-over-black, black-over-green, green-over-red) by redrawing only the corresponding arc portion.
Colors & distances - use a color-picker tool to find the exact RGB values of the colors you are after from those in your sample image. You should also space your rings out horizontally a bit more, and draw the top row closer to the bottom row.
Edit: following my own advice, here's my output
And the program to generate it (import statements ommitted)
public static void paintRing(Graphics2D g, BasicStroke bs, BasicStroke fs,
double x, double y,
double r, double rw, Color color, int a0, int a) {
g.setColor(Color.white);
g.setStroke(new BasicStroke((float)rw*1.5f));
g.drawArc((int)x, (int)y, (int)r, (int)r, a0+5, a-10);
g.setColor(color);
g.setStroke(new BasicStroke((float)rw));
g.drawArc((int)x, (int)y, (int)r, (int)r, a0, a);
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put( RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHints(rh);
double w = getWidth();
// eyeballed measurements
double m = w/12;
double dx = w/7;
double dy = w/8;
double x = m;
double y = .7 * m;
double r = w/4;
// for partial lines
int fwdStart = -30;
int topStart = 90-30;
// background & foreground strokes
float rw = (float)w/40;
BasicStroke bs = new BasicStroke(rw*1.5f);
BasicStroke fs = new BasicStroke(rw);
// colors
Color blue = new Color(0, 133, 199);
Color gold = new Color(244, 195, 0);
Color black = Color.black;
Color green = new Color(0, 159, 61);
Color red = new Color(223, 0, 36);
paintRing(g2d, fs, bs, x, y, r, rw, blue, 0, 360);
paintRing(g2d, fs, bs, x+dx, y+dy, r, rw, gold, 0, 360);
paintRing(g2d, fs, bs, x+2*dx, y, r, rw, black, 0, 360);
// mesh blue-gold-black
paintRing(g2d, fs, bs, x+dx, y+dy, r, rw, gold, topStart, 60);
paintRing(g2d, fs, bs, x, y, r, rw, blue, fwdStart, 60);
paintRing(g2d, fs, bs, x+3*dx, y+dy, r, rw, green, 0, 360);
paintRing(g2d, fs, bs, x+4*dx, y, r, rw, red, 0, 360);
// mesh red-green-black
paintRing(g2d, fs, bs, x+3*dx, y+dy, r, rw, green, topStart, 60);
paintRing(g2d, fs, bs, x+2*dx, y, r, rw, black, fwdStart, 60);
}
public static void main(String[] args) {
JFrame jf = new JFrame("Test");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(new Olympic());
jf.setSize(800, 400);
jf.setLocationByPlatform(true);
jf.setVisible(true);
}

Drawing graphics in Java

I am trying to draw a circle in side a square and having multiple square circles in java. I am almost done but my output isn't coming out as I wanted to. The picture is what I am trying to do but it's not working out.
Here is my code:
a.awt.*;
public class SquaredCircles {
public static final int WIDTH=400;
public static final int HEIGHT=400;
public static void main (String[] args) {
DrawingPanel panel = new DrawingPanel(WIDTH,HEIGHT);
Graphics g = panel.getGraphics ();
panel.setBackground(new Color(0, 255, 255 ) );
int x = 0;
int y = 0;
int size = 100;
int rows = 5;
int numSquares = 1;
drawManySquares ( g, numSquares, x, y, size, rows );
x = 10;
y = 120;
size = 24;
rows = 4;
numSquares = 4;
drawManySquares( g, numSquares, x, y, size, rows );
x = 150;
y = 20;
size = 40;
rows = 6;
numSquares = 5;
drawManySquares( g, numSquares, x, y, size, rows );
x = 130;
y = 275;
size = 36;
rows = 3;
numSquares = 3;
drawManySquares( g, numSquares, x, y, size, rows );
}
public static void drawManySquares( Graphics g, int numSquares, int x, int y, int size, int rows ) {
for ( int i = 0; i < numSquares; i++ ) {
for ( int j = 0; j < numSquares; j++ ) {
drawOneSquare( g, x + i size, y + j size, size, rows );
}
}
}
public static void drawOneSquare( Graphics g, int x, int y, int size, int rows ) {
g.setColor ( Color.GREEN);
g.fillRect(x , y, size, size);
g.setColor ( Color.YELLOW);
g.fillOval ( x, y, size, size);
g.setColor ( Color.BLACK);
g.drawLine(size / 2, x, size / 2, size);
g.setColor ( Color.BLACK);
g.drawLine(x, size / 2, size, size / 2);
for (int i = 0; i <= rows; i = i + 1) {
g.setColor ( Color.BLACK);
g.drawOval(x + (i* (size/rows)), y+ (i*(size/rows)), size - (i*(size/rows +10 )) , size - (i*(size/rows +10)));
}
}
}
Start by having a look at Painting in AWT and Swing and Performing Custom Painting to see how painting should be done in Swing
Break down your problem into manageable chunks. The first thing you need to be able to do is paint a circle of a given size at a specific location, something like
public void paintCircleAt(Graphics2D g2d, int radius, int centerX, int centerY, Color stroke, Color fill) {
Ellipse2D.Double circle = new Ellipse2D.Double(centerX - radius, centerY - radius, radius * 2, radius * 2);
g2d.setColor(fill);
g2d.fill(circle);
g2d.setColor(stroke);
g2d.draw(circle);
}
So, this allows you to paint a circle of a given radius around the center points of x/y filled and outlined with the specified color, pretty simple.
Now, you need someway to paint a series of circles around the same center point, something like...
public void paintCirclesIn(Graphics2D g2d, int count, int radius, int centerX, int centerY, Color stroke, Color fill) {
System.out.println(radius + "; " + centerX + "; " + centerY);
int delta = radius / count;
int innerRadius = radius;
for (int index = 0; index < count; index++, innerRadius -= delta) {
paintCircleAt(g2d, innerRadius, centerX, centerY, stroke, fill);
}
}
Okay, this basically calculates the difference (delta) between each circle and the paints that many circles with that much difference in their radius from the previous one. Because of the way the painting is done, we start with the outer circle and paint in.
And finally, we need someway to paint a square and circles, something like...
public void paintCirclesInSquare(Graphics2D g2d, int count, int x, int y, int width, int height, Color squareStroke, Color squareFill, Color circleStroke, Color circleFill) {
int centerX = x + (width / 2);
int centerY = y + (height / 2);
int radius = Math.min(centerX, centerY);
Rectangle2D box = new Rectangle2D.Double(x, y, width, height);
g2d.setColor(squareFill);
g2d.fill(box);
g2d.setColor(squareStroke);
g2d.draw(box);
paintCirclesIn(g2d, count, radius, centerX, centerY, circleStroke, circleFill);
g2d.drawLine(centerX, y, centerX, y + height);
g2d.drawLine(x, centerY, x + width, centerY);
}
This, again, simply reuses the existing code we already have and adds to it, painting the square, the circles in the square and finally the lines.
Now, from here, you could write a method which took the number of columns/rows you wanted, the x/y position to start from, the size of each of square, the number of circles you need and the colors and reuse this functionality, but I'll leave that up to you ;)
Runnable example for you to play with...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CirclesAndSquares {
public static void main(String[] args) {
new CirclesAndSquares();
}
public CirclesAndSquares() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
int x = getWidth() / 2;
int y = getHeight() / 2;
// paintCircleAt(g2d, Math.min(x, y), y, y, Color.BLACK, Color.YELLOW);
// paintCirclesIn(g2d, 5, Math.min(x, y), x, y, Color.BLACK, Color.YELLOW);
paintCirclesInSquare(g2d, 5, 0, 0, getWidth() - 1, getHeight() - 1, Color.BLACK, Color.GREEN, Color.BLACK, Color.YELLOW);
g2d.dispose();
}
public void paintCirclesInSquare(Graphics2D g2d, int count, int x, int y, int width, int height, Color squareStroke, Color squareFill, Color circleStroke, Color circleFill) {
int centerX = x + (width / 2);
int centerY = y + (height / 2);
int radius = Math.min(centerX, centerY);
Rectangle2D box = new Rectangle2D.Double(x, y, width, height);
g2d.setColor(squareFill);
g2d.fill(box);
g2d.setColor(squareStroke);
g2d.draw(box);
paintCirclesIn(g2d, count, radius, centerX, centerY, circleStroke, circleFill);
g2d.drawLine(centerX, y, centerX, y + height);
g2d.drawLine(x, centerY, x + width, centerY);
}
public void paintCirclesIn(Graphics2D g2d, int count, int radius, int centerX, int centerY, Color stroke, Color fill) {
System.out.println(radius + "; " + centerX + "; " + centerY);
int delta = radius / count;
int innerRadius = radius;
for (int index = 0; index < count; index++, innerRadius -= delta) {
paintCircleAt(g2d, innerRadius, centerX, centerY, stroke, fill);
}
}
public void paintCircleAt(Graphics2D g2d, int radius, int centerX, int centerY, Color stroke, Color fill) {
Ellipse2D.Double circle = new Ellipse2D.Double(centerX - radius, centerY - radius, radius * 2, radius * 2);
g2d.setColor(fill);
g2d.fill(circle);
g2d.setColor(stroke);
g2d.draw(circle);
}
}
}

How to make the player always point to the mouse

Just for fun I thought I would create the game Asteroids. I'm a little bit stuck on the the fact I can't get the player to always look where the mouse is. Here is the player class below.
public class Player extends GameObject {
private int size;
public Player(float x, float y, int width, int height) {
super(x, y, width, height);
size = width / 2 + height / 2;
}
public void update() {
}
public void render(Graphics g) {
Point mouse = MouseInfo.getPointerInfo().getLocation();
int centerX = (int) (mouse.getX() - getX());
int centerY = (int) (mouse.getY() - getY());
double angle = Math.toDegrees(Math.atan2(centerY, centerX));
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.white);
g2d.rotate(angle, (int) getX() + getWidth() / 2, (int) getY() + getHeight() / 2);
g2d.drawLine((int) getX() + getWidth() / 2, (int) getY(), (int) getX(), (int) getY() + getHeight());
g2d.drawLine((int) getX() + getWidth() / 2, (int) getY(), (int) getX() + getWidth(), (int) getY() + getHeight());
g2d.drawLine((int) getX(), (int) getY() + getHeight(), (int) getX() + getWidth() / 2, (int) getY() + getHeight() - size / 6);
g2d.drawLine((int) getX() + getWidth(), (int) getY() + getHeight(), (int) getX() + getWidth() / 2, (int) getY() + getHeight() - size / 6);
}
public Rectangle getBounds() {
return new Rectangle((int) getX(), (int) getY(), getWidth(), getHeight());
}
public void setSize(int size) {
this.size = size;
}
public int getSize() {
return size;
}
}
I guess it sort of works in the fact that if I move my mouse the player does rotate but it rotate pretty fast. So I ask am I doing anything wrong? Before you ask, I have looked it up on Google and found some question like this one but none have helped me.
The argument to Graphics2D.rotate is in radians, not degrees. Try removing Math.toDegrees from the computation of angle. Reference here.
Updated:
Per this comment, getLocation gives the mouse position in screen coordinates, not in the user coordinates of your Graphics2D. You need to convert the coordinates, but how to do that will be specific to your game library.
Updated 2: Assuming GameObject extends java.awt.Component somehow, try getLocationOnScreen (reference here, from the comment noted above):
Point me_absolute = getLocationOnScreen()
int centerX = (int) (mouse.getX() - me_absolute.getX());
int centerY = (int) (mouse.getY() - me_absolute.getY());

canvas.drawBitmap and canvas.drawRect, the draw up object is not the same size

I have a problem with canvas.drawBitmap and canvas.drawRect when i use canvas.drawRect everything works fine but when i use canvas.drawBitmap that when thing start to get strange. The size of the object drawn on the screen are not the same size for DrawRect as for DrawProcentObject. I haven't been able to find a problem with the math in my code so i guess the problem lies in how canvas.drawBitmap works.
I would be grateful if someone could tell me what the problem is and how to solve it.
The width, height is the size of the object here, bmp is a bitmap.
DrawRect(canvas, width, height, x, y, Color.BLACK);
DrawProcentObject(canvas, bmp, x, y, width, height);
the width, height in this method are the screen resolution.
public void DrawObject(Canvas canvas, Bitmap bmp, int X, int Y) {
canvas.save();
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
canvas.drawBitmap(bmp, X, Y, paint);
canvas.restore();
}
public void DrawProcentObject(Canvas canvas, Bitmap bmp, int X, int Y, int SizeWidth, int SizeHeight)
{
double x = width * ((double)X/1000);
double y = height * ((double)Y/1000);
double sizeWidth = width * ((double)SizeWidth/1000);
double sizeHeight = height * ((double)SizeHeight/1000);
bmp = Bitmap.createScaledBitmap(bmp, (int) sizeWidth, (int) sizeHeight, true);
DrawObject(canvas, bmp, (int) x, (int) y);
}
public void DrawRect(Canvas canvas, int SizeWidth, int SizeHeight, int X, int Y, int rectColer)
{
canvas.save();
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
paint.setColor(rectColer);
canvas.drawRect(ProcentRect(SizeWidth, SizeHeight, X, Y), paint);
canvas.restore();
}
public Rect ProcentRect(int SizeWidth, int SizeHeight, int X, int Y)
{
double x = width * ((double)X/1000);
double y = height * ((double)Y/1000);
double sizeWidth = width * ((double)SizeWidth/1000);
double sizeHeight = height * ((double)SizeHeight/1000);
Rect rect = new Rect((int)x, (int)y, (int)x + (int)sizeWidth, (int)y + (int)sizeHeight);
return rect;
}

Categories