Page 2 of 6 FirstFirst 1234 ... LastLast
Results 21 to 40 of 117
  1. #21
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    Quote Originally Posted by Learning Java View Post
    Although I do feel good about having finally complete the task, I do doubt whether I would have been able to do so without your guidance. Even now looking at the code I find it hard to follow what's going on. You broke it up into 4 different methods in advance; I wouldn't have been able to think that far ahead and work that out.

    I just don't feel as if my mind is thinking about solving tasks the way it should be - does that make sense? I think my approach is wrong.
    OK, well your next exercise is the target one, right? Try to implement that on your own, but following the same principals. Maybe describe what you're going to try to do here before you get started.

    If you'll remember Mehran's lecture, when he was talking about "top-down design", the idea is to break things down conceptually and trust that you will be able to write a method to do each of the steps that need to be done.

    We kind of did "bottom-up" design on the Pyramid exercise (actually, top-down conception with bottom-up implementation), in that we wrote the methods to do the basic things first, and built on what we had. True top-down design involves the idea that you write the main code first, calling methods that don't exist yet, and trusting that you'll be able to write those methods. In the real world, at least in my experience, it's always a mix of things anyway. You tackle some part of the project that you know needs to be done, and from which you can get some concrete results, and then you fit other pieces on to that, always maintaining a whole program that compiles, runs, and does something you can recognize.

    By the way, take a look at this alternative drawPyramid()

    Java Code:
            public void drawPyramid(int baseBricks) {
                    // I use doubles just because the ACM graphics objects use them.
                    // For this program, an int works fine.
                    double y = getHeight();
                    for (int i = baseBricks; i > 0; i--) {
                            y -= BRICK_HEIGHT;
                            drawCenteredRowOfBricks(y, i);
                    }
            }
    -Gary-

  2. #22
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    By the way, when you say you find it hard to follow what's going on, I wonder if you are trying to mentally walk through the code and trace your way through each method as you go. While that's a fine skill to have, you also want to be able to consider the methods as black boxes -- trying not to think about the details of their implementation, but rather trust that they will do what they are supposed to do (at least until there is some reason to suspect otherwise). That is part of the philosophy of modular programming, and especially object-oriented programming -- encapsulation. It's being able to use modules of code without thinking about all the implementation details.

    -Gary-

  3. #23
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    Thank you.

    OK, well your next exercise is the target one, right? Try to implement that on your own, but following the same principals. Maybe describe what you're going to try to do here before you get started.
    I've copied the same methods used in the previous exercise and changed the names over.

    drawCircle(double x, double y)
    drawMultipleCircles (double x, double y, numCircles)
    drawCenteredMultipleCircles(double x, double y, numCircles)
    drawTarget(numCircles)

    Does this exercise need to be as general as the last one? Like, in the previous exercise BRICKS_IN_BASE could be changed and the program would do the right thing. I guess that doesn't apply in this exercise since 3 specific radius values have been given for each circle. If that is the case then this exercise would sound more straight forward than the previous one (although, I'm sure I'll find it's not). In that case the last method "drawTarget" wouldn't be needed?

  4. #24
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    Ignore my last post, I didn't think about it at all. I'll think about it and post back after dinner! :)

  5. #25
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    I'm going to try write this out the same way as I'd think about it.

    Right, so I need three circles so I'll have three separate drawCircle methods to draw each circle. The first circle will have a radius of 1 inch and is filled red, the second 0.65 inches and no fill, the third 0.3 inches and filled red. Now I need to work out how to get them to be on top of each other... but I'm not entirely sure how ovals are drawn (where it starts drawing from) although it was mentioned in a lecture. Then before adding them I'll work out where the middle of the window is and subtract half the width of the biggest oval from it (if ovals are in fact drawn from left to right).

  6. #26
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    The following code produces the correct drawing however I should put the math in there to work out the pixels per inch etc to calculate the positioning and size. I don't think the exercise was intended to be done this way :confused:

    Java Code:
    /*
     * File: Target.java
     * Name: 
     * Section Leader: 
     * -----------------
     * This file is the starter file for the Target problem.
     */
    
    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    
    public class Target extends GraphicsProgram {	
    	
    	public void run() {
    
    	drawCircle1(getWidth() / 2 - 72, getHeight() / 2 - 72, 144, 144);
    	drawCircle2(getWidth() / 2 - 47, getHeight() / 2 - 47, 94, 94);
    	drawCircle3(getWidth() / 2 - 22, getHeight() / 2 - 22, 44, 44);
    					
    	}
    	
    	public void drawCircle1(double x, double y, int w, int h) {
    		
    		GOval circle1 = new GOval (x, y, w, h);
    		circle1.setFilled(true);
    		circle1.setFillColor(Color.RED);
    		circle1.setColor(Color.WHITE);
    		add(circle1);
    			
    		}
    	
    	public void drawCircle2(double x, double y, int w, int h) {
    		
    		GOval circle2 = new GOval (x, y, w, h);
    		circle2.setFilled(true);
    		circle2.setFillColor(Color.WHITE);
    		circle2.setColor(Color.WHITE);
    		add(circle2);
    			
    		}
    	
    	public void drawCircle3(double x, double y, int w, int h) {
    		
    		GOval circle3 = new GOval (x, y, w, h);
    		circle3.setFilled(true);
    		circle3.setFillColor(Color.RED);
    		circle3.setColor(Color.WHITE);
    		add(circle3);
    			
    		}
    
    }

  7. #27
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    To be clear, the Pyramid exercise didn't really require the drawPyramid(baseBricks) method -- you could have put that code into run(). Same goes for this exercise. You don't strictly need a drawTarget() method, but it's not that much harder, and the point of the exercise is to learn, not really to draw a target on your screen. :)

    Your breakdown is not bad, but give it just a little more thought. It may be more of a hint than I should be giving you, but I think the key to this exercise is to be able to draw a circle based on its center and radius (oh, and fill color too). That's the method I'd start with.

    -Gary-

  8. #28
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    Sorry, I sent that last post before I saw your last three.

    Your first breakdown (the one you told me to ignore) was in some ways better than the code you wrote. Yes, you need three circles, but that doesn't mean three methods (your Pyramid exercise ended up drawing 105 bricks, but we didn't need 105 methods, did we?). What you really want is one drawCircle method, but instead of x, y, w and h, it should take centerX, centerY, radius (in inches) and fillColor as parameters. That means you need to work out how to translate those values into the x, y, w and h that you need.

    Also, your code uses "magic numbers" -- you have manually worked out a conversion of inches to pixels, and manually entered the pixel values you came up with. It's much better to specify constants with the values we were given in the assignment, and write an inchesToPixels(double inches) method to do the conversion. You (or anybody else reading your code) should never have to stop and think "what does this 94 mean here?"

    -Gary-

  9. #29
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    I know that 1 inch is equal to 72 pixels... if I divide that by 10 I get 7.2 pixels per 0.1 inch. So I can then use that to get the pixels needed for a circle with a radius of 0.65 and 0.3. So what I could have in my code is inches 7.2 / radius to work it out :confused:

    I guess I need to go find out the formula to work out inches into pixels... previously I just converted them using a converter and stuck em in which isn't the most clever thing to do!

  10. #30
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    I see what you're saying. What I should have done is have only one method and called that three times with the correct parameters passed into them. So what I need is another parameter which will set filled to true or false. I don't know why I didn't think of that...

  11. #31
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    Quote Originally Posted by Learning Java View Post
    I see what you're saying. What I should have done is have only one method and called that three times with the correct parameters passed into them. So what I need is another parameter which will set filled to true or false. I don't know why I didn't think of that...
    Well, all of your circles will be filled, just with different colors.

    I steered you wrong a bit in my last post. It would not be good style to have
    Java Code:
            public void drawCircle(double centerX, double centerY, double radius, Color fillColor) {
                    ...
            }
    and have centerX and centerY be in pixels and radius in inches. Better to leave them all pixels, but when you call the method, do something like this:
    Java Code:
            drawCircle(x, y, inchesToPixels(3.5), Color.RED);
    Of course that means you need to write an inchesToPixels() method.

    -Gary-

  12. #32
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    Right I get what you mean now. I didn't know you could pass a color as a parameter. I was selling the fill true/false and of course that's not right because false doesn't equal white as I thought it did for some reason.

    So now I suppose what I need to do is have 3 constants with the radius of each of the circles. Then call a method in the parameters x, y, w, h to work everything out. Right now still stuck on figuring out inches to pixels.

    Java Code:
    /*
     * File: Target.java
     * Name: 
     * Section Leader: 
     * -----------------
     * This file is the starter file for the Target problem.
     */
    
    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    
    public class Target extends GraphicsProgram {	
    	
    	public void run() {
    
    	drawCircle1(getWidth() / 2 - 72, getHeight() / 2 - 72, 144, 144, Color.RED);
    	drawCircle1(getWidth() / 2 - 47, getHeight() / 2 - 47, 94, 94, Color.WHITE);
    	drawCircle1(getWidth() / 2 - 22, getHeight() / 2 - 22, 44, 44, Color.RED);
    					
    	}
    	
    	public void drawCircle1(double x, double y, int w, int h, Color c) {
    		
    		GOval circle1 = new GOval (x, y, w, h);
    		
    		circle1.setColor(c);
    		circle1.setFilled(true);
    		
    		add(circle1);
    			
    		}
    	
    
    }

  13. #33
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    Isn't the "72 pixels per inch" assumption given in the assignment? I'm pretty sure it is. So I would put that value in a constant
    Java Code:
            private static final double PIXELS_PER_INCH = 72.0;
    and then do a simple inchesToPixels() method. The method itself is very simple -- so simple that it doesn't even seem necessary -- but it's there as much for documentation and for readability as for efficiency.
    Java Code:
            public double inchesToPixels(double inches) {
                    return inches * PIXELS_PER_INCH;
            }
    You could just do that multiplication wherever you need the conversion, but putting it into a method makes it clear and explicit what you are doing and why.

    -Gary-

  14. #34
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    I think I'm sort of getting the hang of the whole method calling and parameter thing. Is this ok or should it be broken down even more so that the run method doesn't have to do the math (if that's possible).

    Java Code:
    /*
     * File: Target.java
     * Name: 
     * Section Leader: 
     * -----------------
     * This file is the starter file for the Target problem.
     */
    
    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    
    
    
    public class Target extends GraphicsProgram {	
    	
    		private static final double PIXELS_PER_INCH = 72;
    		private static final double TARGET_ONE = 1.0;
    		private static final double TARGET_TWO = 0.65;
    		private static final double TARGET_THREE = 0.3;
    
    	
    	public void run() {
    		
    		drawCircle1(getWidth() / 2 - inchesToPixels(TARGET_ONE), getHeight() / 2 - inchesToPixels(TARGET_ONE), PIXELS_PER_INCH * TARGET_ONE * 2, PIXELS_PER_INCH * TARGET_ONE * 2, Color.RED);
    		drawCircle1(getWidth() / 2 - inchesToPixels(TARGET_TWO), getHeight() / 2 - inchesToPixels(TARGET_TWO), PIXELS_PER_INCH * TARGET_TWO * 2, PIXELS_PER_INCH * TARGET_TWO * 2, Color.WHITE);
    		drawCircle1(getWidth() / 2 - inchesToPixels(TARGET_THREE), getHeight() / 2 - inchesToPixels(TARGET_THREE), PIXELS_PER_INCH * TARGET_THREE * 2, PIXELS_PER_INCH * TARGET_THREE * 2, Color.RED);
    					
    	}
    	
    	public void drawCircle1(double x, double y, double w, double h, Color c) {
    		
    		GOval circle1 = new GOval (x, y, w, h);
    		
    		circle1.setColor(c);
    		circle1.setFilled(true);
    		
    		add(circle1);
    			
    		}
    	
    	public double inchesToPixels (double xi) {
    		
    		double x = xi * PIXELS_PER_INCH;
    		
    		return x;		
    		
    	}
    	
    }

  15. #35
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    A few points...

    Your drawCircle() method seems to be based on the way GOval works in the ACM libraries, rather than being based on how you really want drawCircle() to work. Your specifications are all about the centers of your circles and their radii, so you really want a method that looks like this:
    Java Code:
            public void drawCircle(double centerX, double centerY, double radius, Color fillColor) {
                    ...
            }
    Now of course you'll have to implement that using the GOval constructors and methods you have available, but the cool thing about encapsulation is that once you have your drawCircle() method, you don't need to think about GOval at all anymore. And it's going to be obvious from looking at your code that it does what the specs say it should do. And writing this method is going to be easier than you might think. You just need to translate the centerX, centerY and radius that you get into an upper-left-corner x and y, and a width and height (which are both the same, since you want a circle). I know you don't have confidence in your math, but it's all been fine so far, and again, part of the beauty of encapsulation is that you keep the mathematical complexity in one place -- you solve the problem once and it stays solved.

    Your inchesToPixels() method is fine, but parameter names are important. I appreciate that you didn't want to just copy the method I wrote, and I respect that. But what does "xi" mean? There is a Greek letter Xi, and there's the Roman numeral for 11, but I don't think you mean either one of those. This is a case where there is an obvious best name for the parameter, so go ahead and call it "inches".

    So yes, you're doing too much math in run(), and what's worse, it's the same math over and over again. Whenever you catch yourself doing the same math more than once, you really should be writing a method instead.
    1. It's clearer.
    2. It's safer. Typing the same math multiple times introduces risk of an undetected keyboard error.
    3. It's more flexible. If you find a better solution for what you're trying to do, it's better if you can change your code in one place, rather than change it in three or five or twenty places.

    Sorry about the rambling, and I hope I'm making some sense. It will become clearer with more experience. I'll just close by offering a run() method for your consideration.
    Java Code:
            public void run() {
                    double screenCenterX = getWidth() / 2;
                    double screenCenterY = getHeight() / 2;
                    drawCircle(screenCenterX, screenCenterY, inchesToPixels(TARGET_ONE), Color.RED);
                    drawCircle(screenCenterX, screenCenterY, inchesToPixels(TARGET_TWO), Color.WHITE);
                    drawCircle(screenCenterX, screenCenterY, inchesToPixels(TARGET_THREE), Color.RED);
            }
    That's the sort of simplicity and readability we're aiming for. Looking at it now, I'm not sure I like those constant names much. It's not clear that they are radius values, so maybe RADIUS1, RADIUS2, and RADIUS3 would be better. This might even be a case where putting in the raw numbers would be acceptable, as long as there's a comment describing where they came from.

    Java Code:
            public void run() {
                    double screenCenterX = getWidth() / 2;
                    double screenCenterY = getHeight() / 2;
                    // per the assignment specification, circle radius values are 1.0, 0.65 and 0.3 inches
                    drawCircle(screenCenterX, screenCenterY, inchesToPixels(1.0), Color.RED);
                    drawCircle(screenCenterX, screenCenterY, inchesToPixels(0.65), Color.WHITE);
                    drawCircle(screenCenterX, screenCenterY, inchesToPixels(0.3), Color.RED);
            }
    I hope I'm not just confusing you more with all this. :)

    -Gary-

  16. #36
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    I think I understand what you mean.

    So what I should be doing is starting from the center of the window and defining the circles pixels from there? So if a circle has a radius of 1 inch (72 pixels) and I'm at the middle of the "canvas" then what I want to do is subtract 72 from the x and y axis and add 72 to the w and h? Or, I might just be talking rubbish here :o

  17. #37
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    Quote Originally Posted by Learning Java View Post
    I think I understand what you mean.

    So what I should be doing is starting from the center of the window and defining the circles pixels from there? So if a circle has a radius of 1 inch (72 pixels) and I'm at the middle of the "canvas" then what I want to do is subtract 72 from the x and y axis and add 72 to the w and h? Or, I might just be talking rubbish here :o
    You need to think a bit more abstractly. We're talking about implementing drawCircle(), right? So you don't care about the center of the window, but only about the centerX and centerY parameters you are being passed. Also, you don't care about inches to pixels conversion, because at this layer you are doing everything in pixels. Your centerX and centerY are in pixels, and your radius is in pixels. So let's start with the simplest part -- if we have a radius, how do we get w and h?

    -Gary-

  18. #38
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    Radius (which is now in pixels) x 2?

  19. #39
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    Quote Originally Posted by Learning Java View Post
    Radius (which is now in pixels) x 2?
    Exactly. And how do we get from centerX and centerY to (upper-left corner) x and y?

    -Gary-

  20. #40
    Learning Java is offline Senior Member
    Join Date
    May 2010
    Location
    London
    Posts
    106
    Rep Power
    0

    Default

    Subtract the radius (in pixels) from centerX and centerY?
    Last edited by Learning Java; 05-11-2010 at 06:49 PM.

Page 2 of 6 FirstFirst 1234 ... LastLast

Similar Threads

  1. Help for University Project
    By ja107 in forum Networking
    Replies: 3
    Last Post: 03-18-2010, 10:22 AM
  2. Help for University Project
    By ja107 in forum Networking
    Replies: 1
    Last Post: 03-04-2010, 12:22 AM
  3. University Of Nottingham Website Survey
    By MuslimCoder in forum Reviews / Advertising
    Replies: 1
    Last Post: 03-02-2009, 10:42 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •