I'm working on a problem I'm having lots of trouble with. The concept of the question is to build a pyramid using bricks. The entire pyramid of bricks is centered in the window. I can draw one brick, then two, then three all the way up until 12 which makes up the base of the pyramid but all of the bricks are alined on the left edge on the left of the window instead of being centered in the window.
Using getWidth() and getHeight() i can do (getWidth()-BRICK_WIDTH) / 2; to get the center for the x coordinate of the brick. And then (getHeight() -BRICK_HEIGHT) / 2; for the center of the y coordinate of one brick. The only problem is i don't understand where to enter that code so it applies to all the bricks so each row of bricks is centered in the window.
import acm.program.*;
import acm.graphics.*;
public class Pyramid extends GraphicsProgram {
public void run() {
double xCoordinate = (getWidth() - BRICKWIDTH) / 2;
double yCoordinate = (getHeight() - BRICK_HEIGHT / 2);
for (int i = 0; i < BRICKS_IN_BASE; i++) {
for (int j = 0; j < i; j++) {
double x = j * BRICK_WIDTH;
double y = i * BRICK_HEIGHT;
GRect square = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
add(square);
}
}
}
private static final int BRICK_WIDTH = 50;
private static final int BRICK_HEIGHT = 25;
private static final int BRICKS_IN_BASE = 12;
}
You should try something like this :
import acm.program.*;
import acm.graphics.*;
public class Pyramid extends GraphicsProgram
{
public void run()
{
// We calculate some values in order to center the pyramid vertically
int pyramidHeight = BRICKS_IN_BASE * BRICK_HEIGHT;
double pyramidY = (getHeight() - pyramidHeight) / 2;
// For each brick layer...
for (int i=BRICKS_IN_BASE ; i >= 1; i--)
{
// We calculate some values in order to center the layer horizontally
int layerWidth = BRICKWIDTH * i;
double layerX = (getWidth() - layerWidth) / 2;
double layerY = pyramidY + (i-1) * BRICK_HEIGHT;
// For each brick in the layer...
for(int j=0 ; j<i ; j++)
{
GRect square = new GRect(layerX + j*BRICK_WIDTH, layerY, BRICK_WIDTH, BRICK_HEIGHT);
add(square);
}
}
}
private static final int BRICK_WIDTH = 50;
private static final int BRICK_HEIGHT = 25;
private static final int BRICKS_IN_BASE = 12;
}
In this implementation, we first calculate the global width of the layer (because we already know how many bricks there will be in it) and we use it to find a global "point of start" of the layer, from which we find all the coordinates for all the rectangles.
You mean something like that?
double x = xCoordinate + j * BRICK_WIDTH;
double y = yCoordinate + i * BRICK_HEIGHT;
Related
What I made:
I drew X and Y Axises and my segments;
I wrote a code, that returns true if the segments intersect.
I wrote a code, that returns the coordinate of an intersection point.
But how I can calculate a ratio does the intersection point divide line segments?
Thanks a lot for your help. ^^
My code is:
package com.staaankey;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Cartesian {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CartesianFrame frame = new CartesianFrame();
frame.showUI();
}
});
}
}
class CartesianFrame extends JFrame {
CartesianPanel panel;
public CartesianFrame() {
panel = new CartesianPanel();
add(panel);
}
public void showUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Main");
setSize(700, 700);
setVisible(true);
}
}
class CartesianPanel extends JPanel {
// x-axis coord constants
public static final int X_AXIS_FIRST_X_COORD = 50;
public static final int X_AXIS_SECOND_X_COORD = 600;
public static final int X_AXIS_Y_COORD = 600;
// y-axis coord constants
public static final int Y_AXIS_FIRST_Y_COORD = 50;
public static final int Y_AXIS_SECOND_Y_COORD = 600;
public static final int Y_AXIS_X_COORD = 50;
//arrows of axis are represented with "hipotenuse" of
//triangle
// now we are define length of cathetas of that triangle
public static final int FIRST_LENGHT = 10;
public static final int SECOND_LENGHT = 5;
// size of start coordinate lenght
public static final int ORIGIN_COORDINATE_LENGHT = 6;
// distance of coordinate strings from axis
public static final int AXIS_STRING_DISTANCE = 20;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// x-axis
g2.drawLine(X_AXIS_FIRST_X_COORD, X_AXIS_Y_COORD,
X_AXIS_SECOND_X_COORD, X_AXIS_Y_COORD);
// y-axis
g2.drawLine(Y_AXIS_X_COORD, Y_AXIS_FIRST_Y_COORD,
Y_AXIS_X_COORD, Y_AXIS_SECOND_Y_COORD);
// x-axis arrow
g2.drawLine(X_AXIS_SECOND_X_COORD - FIRST_LENGHT,
X_AXIS_Y_COORD - SECOND_LENGHT,
X_AXIS_SECOND_X_COORD, X_AXIS_Y_COORD);
g2.drawLine(X_AXIS_SECOND_X_COORD - FIRST_LENGHT,
X_AXIS_Y_COORD + SECOND_LENGHT,
X_AXIS_SECOND_X_COORD, X_AXIS_Y_COORD);
// y-axis arrow
g2.drawLine(Y_AXIS_X_COORD - SECOND_LENGHT,
Y_AXIS_FIRST_Y_COORD + FIRST_LENGHT,
Y_AXIS_X_COORD, Y_AXIS_FIRST_Y_COORD);
g2.drawLine(Y_AXIS_X_COORD + SECOND_LENGHT,
Y_AXIS_FIRST_Y_COORD + FIRST_LENGHT,
Y_AXIS_X_COORD, Y_AXIS_FIRST_Y_COORD);
// draw origin Point
g2.fillOval(
X_AXIS_FIRST_X_COORD - (ORIGIN_COORDINATE_LENGHT / 2),
Y_AXIS_SECOND_Y_COORD - (ORIGIN_COORDINATE_LENGHT / 2),
ORIGIN_COORDINATE_LENGHT, ORIGIN_COORDINATE_LENGHT);
// draw text "X" and draw text "Y"
g2.drawString("X", X_AXIS_SECOND_X_COORD - AXIS_STRING_DISTANCE / 2,
X_AXIS_Y_COORD + AXIS_STRING_DISTANCE);
g2.drawString("Y", Y_AXIS_X_COORD - AXIS_STRING_DISTANCE,
Y_AXIS_FIRST_Y_COORD + AXIS_STRING_DISTANCE / 2);
g2.drawString("(0, 0)", X_AXIS_FIRST_X_COORD - AXIS_STRING_DISTANCE,
Y_AXIS_SECOND_Y_COORD + AXIS_STRING_DISTANCE);
// numerate axis
int xCoordNumbers = 10;
int yCoordNumbers = 10;
int xLength = (X_AXIS_SECOND_X_COORD - X_AXIS_FIRST_X_COORD)
/ xCoordNumbers;
int yLength = (Y_AXIS_SECOND_Y_COORD - Y_AXIS_FIRST_Y_COORD)
/ yCoordNumbers;
// draw x-axis numbers
for(int i = 1; i < xCoordNumbers; i++) {
g2.drawLine(X_AXIS_FIRST_X_COORD + (i * xLength),
X_AXIS_Y_COORD - SECOND_LENGHT,
X_AXIS_FIRST_X_COORD + (i * xLength),
X_AXIS_Y_COORD + SECOND_LENGHT);
g2.drawString(Integer.toString(i),
X_AXIS_FIRST_X_COORD + (i * xLength) - 3,
X_AXIS_Y_COORD + AXIS_STRING_DISTANCE);
}
//draw y-axis numbers
for(int i = 1; i < yCoordNumbers; i++) {
g2.drawLine(Y_AXIS_X_COORD - SECOND_LENGHT,
Y_AXIS_SECOND_Y_COORD - (i * yLength),
Y_AXIS_X_COORD + SECOND_LENGHT,
Y_AXIS_SECOND_Y_COORD - (i * yLength));
g2.drawString(Integer.toString(i),
Y_AXIS_X_COORD - AXIS_STRING_DISTANCE,
Y_AXIS_SECOND_Y_COORD - (i * yLength));
}
//draw first section
int fX1 = 125;
int fY1 = 75;
int fX2 = 135;
int fY2 = 75;
g2.drawLine(fX1, fY1, fX2, fY2);
//draw second section
int sX1 = 130;
int sY1 = 50;
int sX2 = 140;
int sY2 = 150;
g2.drawLine(sX1, sY1, sX2, sY2);
int v1 = (sX2 - sX1) * (fY1 - sY1) - (sY2 - sY1) * (fX1 - sX1);
int v2 = (sX2 - sX1) * (fY2 - sX1) - (sY2 - sY1) * (fX2 - sX1);
int v3 = (fX2 - fX1) *(sY1 - fY1) - (fY2 - fY1) * (sX1 - fX1);
int v4 = (fX2 - fX1) * (sY2 - fY1) - (fY2 - fY1) * (sX2 - fX1);
Boolean result;
if((v1 * v2 < 0) && (v3 * v4 < 0)){
result = true;
}
else{
result = false;
}
System.out.println(result);
int detL1 = det(fX1, fY1, fX2, fY2);
int detL2 = det(sX1, sY1, sX2, sY2);
int x1mx2 = fX1 - fX2;
int x3mx4 = sX1 - sX2;
int y1my2 = fY1 - fY2;
int y3my4 = sY1 - sY2;
int denom = det(x1mx2, y1my2, x3mx4, y3my4);
if(denom == 0){
return;
}
int xnom = det(detL1 ,x1mx2, detL2, x3mx4);
int ynom = det(detL1, y1my2, detL2, y3my4);
int ixOut = xnom / denom;
int iYOut = ynom / denom;
System.out.println("ixOut: ");
System.out.println("iYOut: ");
System.out.println(ixOut);;
System.out.println(iYOut);
}
public int det(int x1, int y1, int x2, int y2){
return x1 * y2 - y1 * x2;
}
}
Use the distance formula, Math.hypot() to calculate the length of the segments. That would be from one end of the line (it's x,y location) to the intersection point. Then from the other lines x,y location to the intersection point. Then divide the smaller length by the larger length. Make certain you use floating point math for the result.
Example:
// some arbitrary line with slope = 5 and y-intercept = 23
UnaryOperator<Integer> y = x->5*x + 23;
int endx = 2;
int endy = y.apply(endx);
int otherendx = 10;
int otherendy = y.apply(otherendx);
int intx = 5;
int inty = y.apply(intx);
double seg1Length = Math.hypot(endx-intx, endy - inty);
double seg2Length = Math.hypot(otherendx-intx, otherendy - inty);
double ratio = Math.min(seg1Length,seg2Length)/Math.max(seg1Length,seg2Length);
prints
Ratio = 0.6
I'm having some problems whit drawing a sierpinski carpet, and would apreciate any help.
I was able to define the stoping condition, draw the central rectangle, and recursively, draw the next level of the image, all while keeping count.
It just so happens that I can only draw on the top left side. I'd say I'm confusing variables, but I can't seem to figure it out. Would apreciate any help
This is the part of the code where i'm having problems.
int smallerWidth = newWidth / 3;
int smallerHeight = newHeight / 3;
int sX = 0;
int sY = 0;
if (currentDeep > 1) {
for (int i = 0; i < 3; i++) {
sX = width / 9 + (i * 3 * (width / 9));
sY = height / 9;
g.fillRect(sX, sY, smallerWidth, smallerHeight);
for (int j = 0; j < 3; j++) {
sY = height / 9 + (j * 3 * (height / 9));
g.fillRect(sX, sY, smallerWidth, smallerHeight);
}
}
return 1 + printSquares(g, sX, sY, newWidth, newHeight, currentDeep
- 1);
} else
return 1;
}
This is the full code
https://pastebin.com/WPJ5tG8w
In sum my question is. What should I change/create in order for my program to draw the remaining 7 squares?
The issue with your code is, that you are trying to perform actions for multiple layers of the recursion at once. Normally, in the recursion, you would only paint the Quadrado central, calculate the sizes and coordinates of the smaller rectangles, and call the method recursively. That way you ensure that the recursive calls do not influence the stuff that is already there.
private int printSquares(Graphics g, int xi, int yi, int width, int height, int currentDeep) {
//Quadrado central
int newWidth = width / 3;
int newHeight = height / 3;
int x = (width / 3) + xi;
int y = (height / 3) + yi;
g.fillRect(x, y, newWidth, newHeight);
int sX = 0;
int sY = 0;
if (currentDeep > 1) {
int sum = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//This is the position of each of the small rectangles
sX = i * (width / 3) + xi;
sY = j * (height / 3) + yi;
// Call the method recursively in order to draw the smaller rectangles
sum += printSquares(g, sX, sY, newWidth, newHeight, currentDeep - 1);
}
}
return 1 + sum;
} else
return 1;
}
I hope, this resolves you issue.
I hope this is ok. This is amazing code. I took the liberty to complete this with the original code provided in the question and added the code that fixed it that Illedhar recommended as a added method. Here it is. Thank you for sharing this.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class sierpinskicarpet {
public static Color BACKGROUNDCOLOR = new Color(0, 0, 150);
public static Color FOREGROUNDCOLOR = new Color(255, 180, 0);
// Padrao = 5, alterado
public static int DEEP = 10;
/**
* Build the frame and shows it
*/
public sierpinskicarpet(int deep) {
// the frame and title
JFrame frame = new JFrame();
frame.setTitle("...: Recursive Squares with deep " + deep + " :...");
// Dispose frame on click on close button
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
// set size and center frame on screen
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
// add print area occupying all the frame content area
frame.add(new PrintArea(deep));
// put frame visible
frame.setVisible(true);
}
/**
* Main method
*/
public static void main(String[] args)
{
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
// launch for 1 to DEEP squares frames
for (int i = DEEP; i >= 1; --i) {
// build a new object each time: objects will run
// independently
new sierpinskicarpet(i);
}
}
});
}
}
/**
* Our print area is, in fact, a label extended with the paint squares behavior
*/
class PrintArea extends JLabel {
private static final long serialVersionUID = 1L;
// local deep variable, will keep the registered deep for this the print
// area
int deep;
/**
* constructor
*/
public PrintArea(int deep) {
// call super, that is JLabel, constructor
super();
// set background color and set as well opaque to allow the background
// to be visible
setBackground(sierpinskicarpet.BACKGROUNDCOLOR);
setOpaque(true);
// save the deep
this.deep = deep;
}
/**
* paint method, called by JVM, when it is needed to update the PrintArea
*/
public void paint(Graphics g) {
// call paint from the JLABEL, draws the background of the PrintArea
super.paint(g);
// set drawing color
g.setColor(sierpinskicarpet.FOREGROUNDCOLOR);
// call the amazing print square method
int n = printSquares(g, 0, 0, getWidth(), getHeight(), this.deep);
// put to the world how much squares we printed
System.out.println("Deep = " + deep + ", squares painted: " + n);
}
/**
* Auxiliary method that will to the work. It must print a square with 1/3
* of the length of the frame and at the center and if not the bottom level
* ask to do the same for each of the other 8 square with 1/3 of length but
* called with the new deep
*/
private int printSquares(Graphics g, int xi, int yi, int width, int height, int currentDeep) {
//Quadrado central
int newWidth = width / 3;
int newHeight = height / 3;
int x = (width / 3) + xi;
int y = (height / 3) + yi;
g.fillRect(x, y, newWidth, newHeight);
int sX = 0;
int sY = 0;
if (currentDeep > 1) {
int sum = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//This is the position of each of the small rectangles
sX = i * (width / 3) + xi;
sY = j * (height / 3) + yi;
// Call the method recursively in order to draw the smaller rectangles
sum += printSquares(g, sX, sY, newWidth, newHeight, currentDeep - 1);
}
}
return 1 + sum;
} else
return 1;
}
}
/*
Works Cited:
Recursive changing variables - sierpinski carpet. Stack Overflow. Retrieved May 4, 2022,
from https://stackoverflow.com/questions/49945862/recursive-changing-variables-sierpinski-carpet
*/
I am a beginning Java user and I am experiencing errors when using two public arrays in a different class. The program is supposed to model 3 interstellar bodies through mathematical integration. Note: I am new to this website and haven't been able to figure the formatting yet.
package gravitationalmodel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class GravitationalModel
{
private Object timer;
private GravitationalObject G1;
private GravitationalObject G2;
private GravitationalObject G3;
public static double[] xArray;
public static double[] yArray;
final public double gravConst = 0.000000000067;
final public int refreshRate = 25;
public GravitationalModel()
{
Timer timer = new Timer(refreshRate, (ActionListener) this); // refreshes model every 25 milliseconds
}
public static void main(String[] args)
{
GravitationalObject G1 = new GravitationalObject(500, 500, 10, 10, 10); // creates 3 interstellar objects taking x position,
GravitationalObject G2 = new GravitationalObject(400, 400, 10, 10, 10); // y position, x veleocity component, y velocity component
GravitationalObject G3 = new GravitationalObject(600, 600, 10, 10, 10); // mass of the object
xArray = new double[1920]; // assigns all elements of array to 0
for (int x = 0; x < 1920; ++x)
{
xArray[x] = 0;
//System.out.println(xArray[x]);
}
yArray = new double[1200];
for (int x = 0; x < 1200; ++x)
{
yArray[x] = 0;
//System.out.println(yArray[x]);
}
}
public void actionPerformed(ActionEvent e) // refreshes model
{
G1.refreshVectorField();
G2.refreshVectorField();
G3.refreshVectorField();
G1.refreshObjects();
G2.refreshObjects();
G3.refreshObjects();
}
}
package gravitationalmodel;
public class GravitationalObject
{
private double xPos; //location and speed of gravitational object
private double yPos;
private double vX;
private double vY;
private double mass;
public GravitationalObject(double x, double y, double xv, double yv, double m)
{
xPos = x;
yPos = y;
vX = xv;
vY = yv;
mass = m;
}
public void refreshVectorField() // calculates gravitational field
{
int k = 1;
for (int x = 0; x < 1920; ++x)
{
if (xPos > x)
k = 1;
else
k= -1;
if (xPos - x == 0)
++x;
xArray[x] += k * (gravConst * mass) / Math.sqrt(xPos - x, 2.0); // errors on this line
}
for (int y = 0; y < 1200; ++y)
{
if (yPos < y)
k = 1;
else
k= -1;
yArray[y] += (gravConst * mass) / Math.sqrt(Math.abs(yPos - y), 2); //errors on this line
}
}
public void refreshObjects()
{
vX += refreshRate/1000 * xArray[xPos]; // errors on these lines
vY += refreshRate/1000 * yArray[yPos];
xPos += refreshRate/1000 * vX;
xPos += refreshRate/1000 * vX;
}
}
You are trying to access GravitationalModel.xArray from GravitationalObject without fully qualifying the static field. Either fully qualify the field, or create a method in GravitationalModel to do the work.
Note that public mutable fields are generally frowned upon in Java, because it breaks encapsulation. It's better to have your objects encapsulate data and behavior via methods, and keep the variables private.
As a beginner, you should not hurry. Soon you would be able to write cool programs. There are lot of errors in this program and even program does not make any logic. You should practice some small programs first to get basics. Like you created following objects which you are not using at all.
GravitationalObject G1 = new GravitationalObject(500, 500, 10, 10, 10); // creates 3 interstellar objects taking x position,
GravitationalObject G2 = new GravitationalObject(400, 400, 10, 10, 10); // y position, x veleocity component, y velocity component
GravitationalObject G3 = new GravitationalObject(600, 600, 10, 10, 10); // mass of the object
Now comes to errors in program.
If you want to access instance variables gravConst or refreshRate in other class, you need to create object of class and access them.
or you can create them static and import them to class like this
import static gravitationalmodel.GravitationalModel.xArray;
import static gravitationalmodel.GravitationalModel.yArray;
import static gravitationalmodel.GravitationalModel.gravConst;
import static gravitationalmodel.GravitationalModel.refreshRate;
Math.sqrt(double) does not take 2 arguments so I think you want to use xArray[x] += k * (gravConst * mass) / Math.pow(xPos - x, 2.0);
and cast double to int as index of array can only be integer as follows
vX += refreshRate / 1000 * xArray[(int)xPos];
vY += refreshRate / 1000 * yArray[(int)yPos];
So your final program is below:
package gravitationalmodel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class GravitationalModel {
private Object timer;
private GravitationalObject G1;
private GravitationalObject G2;
private GravitationalObject G3;
public static double[] xArray;
public static double[] yArray;
final static public double gravConst = 0.000000000067;
final static public int refreshRate = 25;
public GravitationalModel() {
Timer timer = new Timer(refreshRate, (ActionListener) this); // refreshes
// model
// every
// 25
// milliseconds
}
public static void main(String[] args) {
GravitationalObject G1 = new GravitationalObject(500, 500, 10, 10, 10); // creates
// 3
// interstellar
// objects
// taking
// x
// position,
GravitationalObject G2 = new GravitationalObject(400, 400, 10, 10, 10); // y
// position,
// x
// veleocity
// component,
// y
// velocity
// component
GravitationalObject G3 = new GravitationalObject(600, 600, 10, 10, 10); // mass
// of
// the
// object
xArray = new double[1920]; // assigns all elements of array to 0
for (int x = 0; x < 1920; ++x) {
xArray[x] = 0;
// System.out.println(xArray[x]);
}
yArray = new double[1200];
for (int x = 0; x < 1200; ++x) {
yArray[x] = 0;
// System.out.println(yArray[x]);
}
}
public void actionPerformed(ActionEvent e) // refreshes model
{
G1.refreshVectorField();
G2.refreshVectorField();
G3.refreshVectorField();
G1.refreshObjects();
G2.refreshObjects();
G3.refreshObjects();
}
}
and second class as
package gravitationalmodel;
import static gravitationalmodel.GravitationalModel.xArray;
import static gravitationalmodel.GravitationalModel.yArray;
import static gravitationalmodel.GravitationalModel.gravConst;
import static gravitationalmodel.GravitationalModel.refreshRate;
public class GravitationalObject {
private double xPos; // location and speed of gravitational object
private double yPos;
private double vX;
private double vY;
private double mass;
public GravitationalObject(double x, double y, double xv, double yv,
double m) {
xPos = x;
yPos = y;
vX = xv;
vY = yv;
mass = m;
}
public void refreshVectorField() // calculates gravitational field
{
int k = 1;
for (int x = 0; x < 1920; ++x) {
if (xPos > x)
k = 1;
else
k = -1;
if (xPos - x == 0)
++x;
xArray[x] += k * (gravConst * mass) / Math.pow(xPos - x, 2.0); // errors
// on
// this
// line
}
for (int y = 0; y < 1200; ++y) {
if (yPos < y)
k = 1;
else
k = -1;
yArray[y] += (gravConst * mass) / Math.pow(Math.abs(yPos - y), 2); // errors
// on
// this
// line
}
}
public void refreshObjects() {
vX += refreshRate / 1000 * xArray[(int)xPos]; // errors on these lines
vY += refreshRate / 1000 * yArray[(int)yPos];
xPos += refreshRate / 1000 * vX;
xPos += refreshRate / 1000 * vX;
}
}
Hi I'm learning Java and found a solution that is pretty neat,
but I'm interested in a particular line of code in the 2nd for loop.
I wouldn't know who to ask because I'm not in school for Java yet so I'm asking here,
but anyway:
for (int i = 0; i < BRICKS_IN_BASE + (-h); i++)
Does this mean that 'repeat i for this number of times' is added' to 'h minus 1'? More specifically what is (-h)? Is it a pre-increment? And why is it in parenthesis?
It's again used in declaring the variable x.
import acm.graphics.*;
import acm.program.*;
import java.awt.*;
public class Pyramid extends GraphicsProgram {
/** Width of each brick in pixels */
private static final int BRICK_WIDTH = 30;
/** Width of each brick in pixels */
private static final int BRICK_HEIGHT = 12;
/** Number of bricks in the base of the pyramid */
private static final int BRICKS_IN_BASE = 15;
public void run() {
for (int h = 0; h < BRICKS_IN_BASE; h++)
{
for (int i = 0; i < BRICKS_IN_BASE + (-h); i++)
{
int k = i * BRICK_WIDTH;
int m = h * BRICK_HEIGHT;
int x = ((getWidth() - ((BRICKS_IN_BASE + (-h)) * BRICK_WIDTH)) / 2) + k;
int y = getHeight() - ((BRICK_HEIGHT + 1) + m);
GRect brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT);
add(brick);
}
}
}
}
for (int i = 0; i < BRICKS_IN_BASE + (-h); i++)
is really (the (-h) is simply -1*h)
for (int i = 0; i < (BRICKS_IN_BASE - h); i++)
due to operator precedence
I would be very thankful if someone could help me.
My program has 2 classes. One draws a rectangle and a grid, the other is a viewer.
The problem is, when I try to change the position for the greed+rectangle, i.e. update X and Y constants in the Viewer class, the proportions change. The grid fits in only when X=0 and Y=0.
I'm using the same arrays of coordinates to draw the grid and the rectangle, but somehow the proportions are wrong, which surprises me.
Thank you.
My code:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.math.BigDecimal;
public class Viewer extends Applet {
public static final double R_WDTH = 12;//rectangle width
public static final double X = 10;//the grid fits in only when X=Y=0
public static final double Y = 10;
public static final int ROWS = 25;
public static final int COLUMNS = 12;
RectangleAndGrid cup = new RectangleAndGrid(X, Y, R_WDTH, ROWS, COLUMNS);
public void paint(Graphics g) {
cup.draw((Graphics2D)g);
}
}
public class RectangleAndGrid {
private double x, y, blockWidth;
private int rows, columns;
private double coordX[][], coordY[][];
private Rectangle2D.Double cupSpace;
public RectangleAndGrid(double cX, double cY, double givenBlockWidth, int r, int c){
x = cX;
y = cY;
blockWidth = givenBlockWidth;
rows = r;
columns = c;
BigDecimal currX = BigDecimal.valueOf(x);
BigDecimal currY = BigDecimal.valueOf(y);
coordX = new double[rows + 1][columns + 1];
coordY = new double[rows + 1][columns + 1];
for(int i = 0; i <= rows; i++){
for(int j = 0; j <= columns; j++){
coordX[i][j] = currX.doubleValue();
coordY[i][j] = currY.doubleValue();
currX = currX.add(BigDecimal.valueOf(blockWidth));
}
currX = BigDecimal.valueOf(x);
currY = currY.add(BigDecimal.valueOf(blockWidth));
}
cupSpace = new Rectangle2D.Double(coordX[0][0], coordY[0][0], coordX[rows][columns], coordY[rows][columns]);
}
public void draw(Graphics2D g2d){
g2d.setColor(Color.CYAN);
g2d.fill(cupSpace);
g2d.setColor(Color.BLACK);
g2d.draw(cupSpace);
Line2D.Double line = new Line2D.Double();
for(int i = 0; i <= rows; i++){
line.setLine(coordX[i][0], coordY[i][0], coordX[i][columns], coordY[i][columns]);
g2d.draw(line);
}
for(int i = 0; i <= columns; i++){
line.setLine(coordX[0][i], coordY[0][i], coordX[rows][i], coordY[rows][i]);
g2d.draw(line);
}
}
}
Firstly, your approach is a "little" weird, not entirely bad, just a little weird - IMHO
Rectangle2D takes four parameters, x, y, width and height. In you code you are passing the top, left and bottom right corners of your grid, this means, the width/height of your "cup" is actually wider by x pixels (and y pixels higher)
Basically, you need to subtract the x/y offset from the bottom right coordinates...
cupSpace = new Rectangle2D.Double(coordX[0][0], coordY[0][0], coordX[rows][columns] - coordX[0][0], coordY[rows][columns] - coordY[0][0]);