Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am making a star using a draw line. I want to run a for loop to expand a star into multiple stars in a grid-like pattern. I am fairly new to java and could use some help with my code. The gride pattern that I would like the stars to open up too isn't too specific as far as columns x rows go. even making 6 stars or 9 stars is fine, as long as they are in a grid-like pattern.
So far, I have the star drawn with drawLine. At one point I got two stars but they were to close to each other. When I run the code it looks like I have a whole bunch of stars sort of staggered on top of each other and being able to get two stars on Star Field, I would like to get more in such 5x6 pattern or something close. I believe I might be having a hard time computing the math in the for loops to get this to happen.
Should I run, multiple nested for loops or is there a way to do this with using a minimal amount of for loops?
public static void drawFlag(int stars, int stripes, java.awt.Graphics
g, int x, int y, int width, int height) {
// Sets backround rectangle color to white
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
// Draw filled red rectangles *stripes*
int stripeHeight = height/stripes;
g.setColor(Color.RED);
int lastStripeDrawnY = 0;
// For loop runs red stripes
for (int i = y; i < y + height - 2*stripeHeight; i = i + 2*stripeHeight)
{
g.fillRect(x, i, width, stripeHeight);
lastStripeDrawnY = i;
}
// expands strips across the rectangle
int lastStripeY = lastStripeDrawnY+2*stripeHeight;
int lastStripeHeight = y + height - lastStripeY;
if (stripes%2 != 0) {
g.fillRect(x, lastStripeY, width, lastStripeHeight);
}
int stars1 = 15;
for (int cols = 1; cols <= stars1; cols++) {
int rows = stars1/cols;
if (cols > rows && cols <2*rows && cols*rows == stars1) {
}
}
// Draws the starField
int numberOfRedStripes = (int)Math.ceil(stripes/2.0);
int starFieldHeight = numberOfRedStripes*stripeHeight;
int starFieldWidth = starFieldHeight*width/height;
g.setColor(Color.BLUE);
g.fillRect(x, y, starFieldWidth, starFieldHeight);
for (int x1 = 0; x1+100 <+ starFieldWidth-5; x1++) {
if(x1/5*4 == stars) {
drawStar(g,x1,y,50);
for(int y1 = 0; y1 <=starFieldHeight-5;y1++) {
if(y1/4*2 == stars) {
drawStar(g,x,y1,50);
}
}
}
}
}
// drawLine the star
public static void drawStar(java.awt.Graphics g, int x, int y, int size)
{
g.setColor(Color.WHITE);
g.drawLine(x+size/2, y+size/6, x+4*size/5, y+5*size/6);
g.drawLine(x+4*size/5,y+5*size/6, x+size/6, y+2*size/5);
g.drawLine(x+size/6, y+2*size/5, x+5*size/6, y+2*size/5);
g.drawLine(x+5*size/6, y+2*size/5, x+size/5, y+5*size/6);
g.drawLine(x+size/5, y+5*size/6, x+size/2, y+size/6);
}
}
Expand one star into a checkered grid-like pattern.
There are a number of ways you can approach this problem, you can, as you've started, simply try and build each star individually based on the required x/y position.
You could make a single star that was always at 0x0 and translate the Graphics context to the desire x/y position
Or, you could take advantage of the Shape API.
This allows you to define a self contained object which describes the shape you are trying to create.
public class StarShape extends Path2D.Double {
public StarShape(double size) {
double mid = size / 2d;
moveTo(mid, 0);
lineTo((size * 0.6d), (size * 0.4d));
lineTo(size, (size * 0.4d));
lineTo((size * 0.72d), (size * 0.58d));
lineTo((size * 0.85d), size);
lineTo((size * 0.5d), (size * 0.72d));
lineTo((size * 0.2), size);
lineTo((size * 0.325d), (size * 0.58d));
lineTo(0, (size * 0.4d));
lineTo((size * 0.4d), (size * 0.4d));
closePath();
}
}
There are lots of side benefits to this, but the immediate benefit is that it's "paintable". You can pass an instance of it directly to Graphics2D and have it painted and/or filled based on your needs.
Now, with that in hand, you can do something like...
public class TestPane extends JPanel {
private StarShape star;
private double starSize = 10;;
public TestPane() {
star = new StarShape(starSize);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double y = 0;
for (int yIndex = 0; yIndex < getHeight() / starSize; yIndex++) {
double x = 0;
for (int xIndex = 0; xIndex < getWidth() / starSize; xIndex++) {
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
PathIterator path = star.getPathIterator(at);
GeneralPath p = new GeneralPath();
p.append(path, true);
g2d.fill(p);
x += starSize;
}
y += starSize;
}
g2d.dispose();
}
}
The reason I'd prefer this method, is it doesn't affect the origin of the original starShape. You could also use the technique to cache the results, so you're not repeatedly doing it in the paintComponent method.
You could also do something like...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double y = 0;
for (int yIndex = 0; yIndex < getHeight() / starSize; yIndex++) {
double x = 0;
for (int xIndex = 0; xIndex < getWidth() / starSize; xIndex++) {
Graphics2D starg = (Graphics2D) g2d.create();
starg.translate(x, y);
starg.fill(star);
starg.dispose();
x += starSize;
}
y += starSize;
}
g2d.dispose();
}
Which changes the origin of the Graphics context instead or something like...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double xCount = getWidth() / starSize;
for (int yIndex = 0; yIndex < getHeight() / starSize; yIndex++) {
for (int xIndex = 0; xIndex < getWidth() / starSize; xIndex++) {
g2d.fill(star);
star.transform(AffineTransform.getTranslateInstance(starSize, 0));
}
star.transform(AffineTransform.getTranslateInstance(-(starSize) * xCount, starSize));
}
g2d.dispose();
}
which changes the origin of the star itself.
Personally, I prefer not to affect the original and instead simply change the context in how it's painted, but which method you use will come down to your needs.
Okay, that might seem like a lot of work for little gain, but the Shapes API is extremely powerful. Because it's point based (instead of pixel based), it can be more easily resized, without generating pixilation. It's very simple to rotate, through the use of AffineTransform and makes for a much simpler point of re-use.
Want to make the stars bigger? Simply change starStar, for example...
private double starSize = 50;
and the API takes care of the rest...
I used your drawStar() function and built this StarPanel. Try it and see if it gives you some hints for what you are trying to achieve.
Note that I removed g.setColor(Color.WHITE); line from your drawStar() function. We need to be careful when we set color of Graphics object. In many cases, this is the reason why we don't see what we draw.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
public class StarPanel extends JPanel
{
private int xStarting;
private int yStarting;
private int numberOfRows;
private int numberOfColumns;
private int xDisplacement;
private int yDisplacement;
public StarPanel(int xStarting, int yStarting,
int numberOfRows, int numberOfColumns,
int xDisplacement, int yDisplacement)
{
this.xStarting = xStarting;
this.yStarting = yStarting;
this.numberOfRows = numberOfRows;
this.numberOfColumns = numberOfColumns;
this.xDisplacement = xDisplacement;
this.yDisplacement = yDisplacement;
}
public static void main(String[] args)
{
StarPanel starPanel = new StarPanel(50, 50, 5, 6, 75, 75);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(starPanel);
frame.setBounds(300, 200, 500, 600);
frame.setVisible(true);
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
for (int row = 0; row < numberOfRows; row++) {
for (int column = 0; column < numberOfColumns; column++) {
drawStar(g, xStarting + (row * xDisplacement), yStarting + (column * yDisplacement), 50);
}
}
}
// drawLine the star
public static void drawStar(java.awt.Graphics g, int x, int y, int size)
{
g.drawLine(x+size/2, y+size/6, x+4*size/5, y+5*size/6);
g.drawLine(x+4*size/5,y+5*size/6, x+size/6, y+2*size/5);
g.drawLine(x+size/6, y+2*size/5, x+5*size/6, y+2*size/5);
g.drawLine(x+5*size/6, y+2*size/5, x+size/5, y+5*size/6);
g.drawLine(x+size/5, y+5*size/6, x+size/2, y+size/6);
}
}
Related
I am attempting to draw the US flag using java. I have pretty much done all this coding using lots of variables. It should be at least displaying the stripes, blue box, and the stars(ovals in this case). However, when I run the code through the compiler, and run it, all it displayes is a white background with a red stripe on the top. Could I please receive some help to see where my error is? I have tried everything.
Here is the code:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
public class UsFlag extends JPanel {
int w = getWidth();
int h = getHeight();
int numberStripes = 13;
int numStarCol = 8;
int numStarRow = 6;
int stripeHeight = h/numberStripes;
int boxWidth = (int)(w*0.4);
int boxHeight = 7 * stripeHeight;
int starWidth = boxWidth/numStarCol;
int starHeight = boxHeight/numStarRow;
/*public UsFlag() {
//ask user to enter number of stripes, star columns, and star rows
}*/
#Override
public void paintComponent(Graphics g) {
int w = getWidth();
int h = getHeight();
//Background
g.setColor(Color.RED);
g.fillRect(0, 0, w, h);
//Stripes
g.setColor(Color.WHITE);
for (int i = 0; i < numberStripes; i += 1) {
g.fillRect(0,stripeHeight, w, stripeHeight);
stripeHeight = stripeHeight + 45;
}
//Blue Rect
g.setColor(Color.BLUE);
g.fillRect(0, 0, boxWidth, boxHeight);
//stars
int y = 0;
int x = 0;
for (int j = 0; j < numStarRow; j++){
for (int i = 0; i < numStarCol; i++){
g.setColor(Color.WHITE);
g.fillOval(5, 5, starWidth, starHeight);
x += starWidth;
}
y += starHeight;
x = 0;
}
}
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(400, 400);
window.setContentPane(new UsFlag());
window.setVisible(true);
}
}
The first two parameters for the fillRect() method and the fillOval() method are considered coordinates (x & y) for the object you want to paint. This means that for x you need to place a integer pixel value as to where you want the Left edge of the object is to Start being painting from along the horizontal plain, and for y you need to place a integer pixel value as to where you want the Top edge of the object is to Start being painting from along the vertical plain. For fillRect() for example:
g.fillRect(20, 20, 100, 30);
The other two parameters are for the Width (w) and Height (h) in pixels of the object to paint. Use the the variable i from your for loop (y = i + 30; for example) to draw objects below one another. Read this for more information.
i have an arraylist RecArray of objects with each object containing two int values, one for the width and for the height of a rectangle. Each rectangle's height and width are a multiple of ten. the rectangles have to be passed on to the surface as in the given order in RecArray from left to right and from top to bottom. my problem is i can not find the x,y coordinates of the next rectangle. what im trying to do is, starting at the coordinate (0,0) i generate the first rectangle, add it to an arraylist RecList. Then i set the x and y coordinates. x becomes x = x+RecArray.get(0).getLength1() + 1. if x is greater than the width of the jpanel surface then it becomes 0 and y becomes y = y + 10 . starting from the second object in the RecArray i try to generate rectangles with the given coordinates and width&height. Then i try to compare them with all the previous rectangles to see if there is any overlapping. if there is no overlapping, the rectangle will be drawn, if there is overlapping, the x coordinate of the rec becomes x = RecList.get(j).width+1 and if that exceeds the width x becomes 0 and y is y=y+10. Then i regenate the current rectangle with the new coordinates and compare with the other rectangles in RecList again till i find the right spot for the current rectangle.ive been dealing with that issue for the last 5 days and am really fed up now. i would greatly appreciate any tipps. and Please be patient with me. im still learning programming.
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Rectangle rec = new Rectangle(x, y, RecArray.get(0).getWidth(),
RecArray.get(0).getHeight());
RecList.add(rec);
recPaint(g2,RecArray.get(0));
x = x + RecArray.get(0).getWidth() + 1;
int i;
for (i = 1; i < RecArray.size(); i++) {
if (x >= this.getArea().getWidth()) {
x = 0;
y = y + 10;
}
Rectangle rec1 = new Rectangle(x, y, RecArray.get(i)
.getWidth(), RecArray.get(i).getheight());
for (int j= 0; j < RecList.size(); j++) {
if (!recIntersect(rec1, RecList.get(j))) {
RecList.add(rec1);
recPaint(g2,RecArray.get(i));
break;
}
else {
x = RecList.get(j).width;
if (x >= this.getFlaeche().getLength1()) {
x = 0;
y = y + 10;
}
rec1 = new Rectangle(x, y,RecArray.get(i). .getWidth(),
RecArray.get(i).getHeight());
}
x = x + RecArray.get(i).getWidth();
}
//With this method using the given rec parameter a rectangle will be drawn on the g2 and filled in blue colour
private void recPaint (Graphics2D g2, RecType rec){
g2.setColor(Color.BLUE);
g2.fillRect(x, y, rec.getWidth(),
rec.getLength2());
g2.setColor(Color.BLACK);
g2.drawRect(x, y, rec.getHeight(),
rec.getLength2());
}
// returns true, if two rectangles overlap
private boolean recIntersect(Rectangle rec1, Rectangle rec2) {
if( rec1.intersects(rec2)){
return true;
}
return false;
}
Edit: apparently i haven't stated clearly what my problem is. my problem is, that the way i generate (x,y) coordinates of the rectangles is obviously wrong. the way my algorithm works doesnt get the results i want. i want my rectangles to be placed neatly next to/above/below each other WITHOUT overlapping, which is not the case.
Separate out your List of Rectangles. Calculate the X, Y coordinates once.
Since I didn't have your object class, I used the Dimension class, which holds a width and a length. I used the Rectangle class to hold the objects that will eventually be drawn in your Swing GUI.
Divide and conquer. Separate out your GUI model, view, and controller(s). This way, you can focus on one piece of the puzzle at a time.
Here are the results of my test code when I ran it with a drawing area of 500, 400.
java.awt.Rectangle[x=0,y=0,width=100,height=100]
java.awt.Rectangle[x=100,y=0,width=20,height=10]
java.awt.Rectangle[x=120,y=0,width=40,height=20]
java.awt.Rectangle[x=160,y=0,width=60,height=40]
java.awt.Rectangle[x=220,y=0,width=80,height=60]
java.awt.Rectangle[x=300,y=0,width=20,height=10]
java.awt.Rectangle[x=320,y=0,width=120,height=110]
Here are the results of my test code when I ran it with a drawing area of 200, 200.
java.awt.Rectangle[x=0,y=0,width=100,height=100]
java.awt.Rectangle[x=100,y=0,width=20,height=10]
java.awt.Rectangle[x=120,y=0,width=40,height=20]
java.awt.Rectangle[x=0,y=100,width=60,height=40]
java.awt.Rectangle[x=60,y=100,width=80,height=60]
java.awt.Rectangle[x=140,y=100,width=20,height=10]
And here's the code. I fit rectangles on the X axis until I can't fit another rectangle. Then I add the maximum height to Y, reset the X to zero, reset the maximum height and fit the next row of rectangles.
Create test applications like I did here and make sure that you can create the GUI model long before you create the GUI view and GUI controller.
package com.ggl.testing;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
public class CalculatingRectangles {
public static void main(String[] args) {
CalculatingRectangles calculatingRectangles = new CalculatingRectangles();
Dimension drawingArea = new Dimension(200, 200);
List<Dimension> dimensions = new ArrayList<>();
dimensions.add(new Dimension(100, 100));
dimensions.add(new Dimension(20, 10));
dimensions.add(new Dimension(40, 20));
dimensions.add(new Dimension(60, 40));
dimensions.add(new Dimension(80, 60));
dimensions.add(new Dimension(20, 10));
dimensions.add(new Dimension(120, 110));
List<Rectangle> rectangles = calculatingRectangles
.calculatingRectangles(drawingArea, dimensions);
System.out.println(displayRectangles(rectangles));
}
private static String displayRectangles(List<Rectangle> rectangles) {
StringBuilder builder = new StringBuilder();
for (Rectangle r : rectangles) {
builder.append(r);
builder.append(System.getProperty("line.separator"));
}
return builder.toString();
}
public List<Rectangle> calculatingRectangles(Dimension drawingArea,
List<Dimension> dimensions) {
int width = drawingArea.width;
int height = drawingArea.height;
int x = 0;
int y = 0;
int index = 0;
int maxHeight = 0;
boolean hasRoom = dimensions.size() > index;
List<Rectangle> rectangles = new ArrayList<>();
while (hasRoom) {
Dimension d = dimensions.get(index);
maxHeight = Math.max(maxHeight, d.height);
if ((x + d.width) <= width && (y + maxHeight) <= height) {
Rectangle r = new Rectangle(x, y, d.width, d.height);
x += d.width;
rectangles.add(r);
index++;
if (index >= dimensions.size()) {
hasRoom = false;
}
} else {
y += maxHeight;
if (y > height) {
hasRoom = false;
}
x = 0;
}
}
return rectangles;
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I'm trying to use a double that has a very small value to produce one of a more regular size. For example, dividing 1/(double) would produce something like 14.12848572.... I then cast this double into an int to produce a number which I can use to draw an image in a JPanel.
The issue I've been having is that the image does not draw how I expect it to draw. I think this is because there's something I don't understand about how casting doubles works. Anyone who can tell me a bit about how this process actually goes down would be very helpful.
EDIT:
The purpose of this code is translating a monetary value into the size of a bar on a graph. The size of these bars should change as the value changes so that they utilize space in the most efficient manner.
Therefore...
Due to the nature of the monetary values, max will never be less than 430.
I want the image to be bigger the smaller xscale is. If there are fewer values to graph, xscale is smaller, and then the bars are drawn bigger.
EDIT:
The following image shows what my program is currently drawing. What I would like to draw is a series of bars on a bar graph. The xscale and associated variables are what I am primarily concerned with right now.
EDIT:
The SSCCE is completed (I think)! If you run this code, you will see the drawing I don't want. If you change barwidth to equal 7 or some normal int, you will see something that is more along the lines of what I want drawn. Please let me know if there is anything more I should do to make things easier!
EDIT: Copy/pasted wrong code, has been corrected (derp)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class castingexample extends JPanel
{
private static int ypoint;
private static int barheight;
private static Color color;
private static int bars = 10;
private static int xpoint = 0;
private static int barwidth = 7;
private static double xscale = 7;
private static int yscaleplus = 10000;
private static int yscaleneg = 0;
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new castingexample());
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
}
public castingexample()
{
new Timer(100, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
resize();
repaint();
}
}).start();
}
public void resize()
{
xscale = bars/(800 - bars*5);
xscale = 1/xscale;
}
public void paintComponent (Graphics g)
{
super.paintComponent(g);
for (int i = 0; i < bars; i++)
{
barheight = 200;
barwidth = (int) (xscale);
ypoint = 450 - barheight;
xpoint = 105+(barwidth + 5)*i;
if(ypoint < 450)
color = Color.green;
else
color = Color.red;
g.setColor(color);
g.fillRect(xpoint, ypoint, barwidth, barheight);
}
}
}
Here's some relevant code:
public void resize()
{
int max = 0;
int min = 0;
for (int i = 0; i < bars; i++)
{
if (getTime(i) > max)
max = (int)getTime(i);
}
yscaleplus = max/430;
/*
for (int i = (int)(getLife() - getRetire() + 1); i < bars; i++)
{
if (getTime(i) < min)
min = (int)getTime(i);
}
yscaleneg = Math.abs(min/200);
*/
xscale = bars/(800 - bars*5);
xscale = 1/xscale;
}
public void paintComponent (Graphics g)
{
super.paintComponent(g);
g.drawLine(100, 20, 100, 630);
g.drawLine(100, 450, 900, 450);
for (int i = 0; i < bars; i++)
{
barheight = (int) (getTime(i)/yscaleplus);
barwidth = (int) (xscale);
ypoint = 450 - barheight;
xpoint = 105+(barwidth + 5)*i;
if(ypoint < 450)
color = Color.green;
else
color = Color.red;
g.setColor(color);
g.fillRect(xpoint, ypoint, barwidth, barheight);
}
}
doubles do not store information as you seem to think, they store information as a value followed by an exponential value of 2^x, this removes the capability you are trying to use
take a look at Math.round(x) instead.
I'm making a map editor for an isometric game, and I'm a bit stuck on rendering an isometric guide grid (a grid that shows where objects will be placed). That is, I need to draw lines across a Graphics object in such a way that it forms a grid with cells of variable width and height. What can I do to accomplish this?
So far I have:
//The number of cells in each direction
int nv=h/cellh;
int nh=w/cellw;
for(int i=1;i<=nv;++i){
g.drawLine(0,i*cellh,i*cellh*2,0);
}
But that just draws bottom left to upper right lines that begin on the left side.
This will work as you expect:
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
int width = getWidth();
int height = getHeight();
int sizeW = 50;
int sizeH = 50;
int countW = width / sizeW;
int countH = height / sizeH;
for (int i = 0; i <= countW + countH; i++) {
g.drawLine(0, i * sizeH, i * sizeH, 0);
g.drawLine(width - i * sizeW, 0, width, i * sizeW);
}
}
I want to make a simple stairway line having an interval distance of 200 meters in every line. As you can see in the code, it has a screen height(y1_world) of 2000 meters and a screen width(x1_world) of 1125. The code works only in a slant position of lines and not in a stairway and that is my problem.
Could someone give me an idea about this matter?
Here's the code:
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setBackground(Color.white);
int x0_pixel = 0;
int y0_pixel = 0;
int x1_pixel = getWidth();
int y1_pixel = getHeight();
int x0_world = 0;
int y0_world = 0;
int x1_world = 2000; // meters
int y1_world = 1125; // meters
double x_ratio = (double) x1_pixel / x1_world;
double y_ratio = (double) y1_pixel / y1_world;
double len = x1_world; // meters
double interval = 200; // meters
int x_world = 0;
int y_world = 0;
while (((y_world += interval) <= y1_world) && ((x_world +=interval) <= x1_world))
{
int x_pixel = convertToPixelX(x_world, x_ratio);
int y_pixel = convertToPixelY(y_world, y_ratio);
g2d.setColor(Color.BLUE);
g2d.drawLine(x_world, y_world, x_pixel, y_pixel);
}
Toolkit.getDefaultToolkit().sync();
g2d.dispose();
}
private static int convertToPixelY(int y_world, double y_ratio)
{
return (int) (y_world * y_ratio);
}
private static int convertToPixelX(int x_world, double ratio)
{
return (int) (x_world * ratio);
}
You're doing too little: you should draw a line up, then a line to the right. If I were you, I would encapsulate that in a 'stair' function:
public void step( Graphics2d g ) {
Point midPoint = getMidPoint();
Point endPoint = getEndPoint();
drawStep( g, currentPoint, midPoint, endPoint );
currentPoint = endPoint;
}
public void drawStep( Graphics2d g, Point first, Point mid, Point last ) {
g.drawLine( first.x, first.y, mid.x, mid.y );
g.drawLine( mid.x, mid.y, last.x, last.y );
}
public Point getMidPoint(){
return new Point( currentPoint.x, currentPoint.y + stepHeight );
}
public Point getEndPoint(){
return new Point( currentPoint.x + stepWidth, currentPoint.y + stepHeight );
}
You're doing too much, too: scaling your image to your viewport happens to be the specialty of AffineTransform (here's a brief intro)
public void paint( Graphics gx ) {
Graphics2D g = (Graphics2D) gx;
AffineTransform scale = AffineTransform.getScaleInstance(
xPixels/numberOfSteps*stepWidth,
yPixels/numberOfSteps*stepHeigth );
g.transform(scale);
for( int i = 0; i < numberOfSteps; ++ i ) {
step( g );
}
}
Disclaimer: code is uncompiled, untested - intended to give a hint.
A single drawLine does not draw a stair. You have to draw two lines: A horizontal and a vertical one:
g2d.drawLine(x_world, y_world, x_pixel, y_world); // keep y constant
g2d.drawLine(x_pixel, y_world, x_pixel, y_pixel); // keep x constant
This may not be the right answer, but it seems like you might need to setup a loop to draw the lines in a step shape:
bool vert = false;
while(x_pixel <= x_world){
if (vert){
g.drawLine(x, y);
vert = True;
else{
g.drawLine(y,x);
vert = False;
This is not the exact code! Just a general idea of what might work.
I hope this makes sense. You are just trying to get it to draw a vertical line first then a horizontal line, then repeat. Rather than just one long line.