Alright, so I am having a problem writing this program. I have the first part done but I don't know how to finish it. I've tried different solutions and everything, but yet I still have no clue. Here is what I have so far. What I need to do is make this where it will start in all four corners.
public void paintComponent( Graphics g )
{
super.paintComponent( g );
int width = getWidth();
int height = getHeight();
int number, x, y, dx, dy;
x = 0;
y = height;
number = 15;
dx = width / number;
dy = height / number;
for ( int i = 1; i < number; i++ )
{
x += dx;
y -= dy;
g.drawLine( 0, 0, x, y );
}
}
I gather that you want to draw a fan-out of 15 lines from each corner to the facing diagonal. I'd suggest writing a routine to draw a fan from a point to an arbitrary line segment and then use that:
drawFan(Graphics g,
int number, // number of fan lines
int x0, int y0, // coordinates of the point
int sx, int sy, // coordinates of the line segment start
int ex, int ey) // coordinates of the line segment end
{
int x = sx,
y = sy,
dx = (ex - sx) / number,
dy = (ey - sy) / number;
for (int i = 1; i < number; ++i) {
x += dx;
y += dy;
g.drawLine(x0, y0, x, y);
}
}
You can then call this with the appropriate values for each corner and diagonal.
public void paintComponent( Graphics g )
{
super.paintComponent( g );
int width = getWidth();
int height = getHeight();
drawFan(g, 15, 0, 0, 0, height, width, 0); // top left corner
drawFan(g, 15, 0, height, 0, 0, width, height); // bottom left corner
drawFan(g, 15, width, height, 0, height, width, 0); // bottom right corner
drawFan(g, 15, width, 0, 0, 0, width, height); // top right corner
}
Here is the solution, my suggestion is to understand how the coordinate system works in Java then It'll be easy.
public void paintComponent( Graphics g ){
super.paintComponent(g);
int widthX = getWidth();
int heightY = getHeight();
int num, i, j;
num = 15;
i = 0;
j = 15;
while( i != 16 && j != -1 ){
g.drawLine( 0, 0, widthX*i/num, heightY*j/num );
g.drawLine( widthX*i/num, heightY*j/num, widthX, heightY );
g.drawLine( widthX*i/num, heightY*i/num, widthX, 0);
g.drawLine( widthX*j/num, heightY*j/num, 0, heightY);
i++;
j--;
}//end while
}//end method paintComponent
Related
When I run the code it generates 16 rectangles with a random size, random position, and a random color. It is then supposed to turn white if it is colliding with another rectangle. Most of the time it works fine but every so often rectangles turn white when they are not colliding with anything.
Main
int boxCount = 16;
Box[] boxes = new Box[boxCount];
void setup(){
size(500, 500);
for(int i = 0; i < boxCount; i++){
boxes[i] = new Box(random(50, width - 50), random(50, height - 50), random(20, 50), random(20, 50), color(random(0, 255), random(0, 255), random(0, 255)));
}
}
void draw(){
for(int i = 0; i < boxCount; i++){
boxes[i].create();
for(int x = 0; x < boxCount; x++){
if(boxes[i] != boxes[x]){
boxes[i].collide(boxes[x]);
}
}
}
}
Class
class Box{
float x;
float y;
float w;
float h;
color c;
Box(float _x, float _y, float _w, float _h, color _c){
x = _x;
y = _y;
w = _w;
h = _h;
c = _c;
}
void create(){
fill(c);
rect(x, y, w, h);
}
void collide(Box o){
float right = x + (w / 2);
float left = x - (w / 2);
float top = y - (h / 2);
float bottom = y + (h / 2);
float oRight = o.x + (o.w / 2);
float oLeft = o.x - (o.w / 2);
float oTop = o.y - (o.h / 2);
float oBottom = o.y + (o.h / 2);
if(right > oLeft && left < oRight && bottom > oTop && top < oBottom){
c = color(255, 255, 255);
}
}
}
rect doesn't draw a rectangle around center point, by default the rectangle is drawn at a top left position (x, y) with a size (with, height).
You've 2 possibilities to solve the issue:
Either change the collision detection method:
class Box{
// [...]
void collide(Box o){
if(x < o.x+o.w && o.x < x+w && y < o.y+o.h && o.y < y+h){
c = color(255, 255, 255);
}
}
}
Or set the CENTER rectMode(), which will cause the rectangle to be drawn as you expect it:
class Box{
// [...]
void create(){
fill(c);
rectMode(CENTER);
rect(x, y, w, h);
}
// [...]
}
I want to plot a given character into a console application, shaping an ellipse.
The problem I don't know how to solve is that I only know where to draw a character once I know the angle and the radius (with Sin and Cos functions), but then I may leave gaps.
It's even more complex, because I want to "draw" a filled ellipse, not only the border.
How can I do it?
The method I want is like this:
DrawEllipse(char ch, int centerX, int centerY, int width, int height)
Just an idea: I may write a loop with an inner loop in the rectangle area of the ellipse and determine if a position is inside or outside the area of the ellipse.
This will be a reasonable approximation.
public static void DrawEllipse( char c, int centerX, int centerY, int width, int height )
{
for( int i = 0; i < width; i++ )
{
int dx = i - width / 2;
int x = centerX + dx;
int h = (int) Math.Round( height * Math.Sqrt( width * width / 4.0 - dx * dx ) / width );
for( int dy = 1; dy <= h; dy++ )
{
Console.SetCursorPosition( x, centerY + dy );
Console.Write( c );
Console.SetCursorPosition( x, centerY - dy );
Console.Write( c );
}
if( h >= 0 )
{
Console.SetCursorPosition( x, centerY );
Console.Write( c );
}
}
}
To start off, here is how to draw a filled circle (assuming a 80x25 console window). Someone else might know the maths to allow width and height parameters.
static void DrawCircle(char ch, int centerX, int centerY, int radius)
{
for(int y = 0; y < 25; y++)
{
for(int x = 0; x < 80; x++)
{
char c = ' ';
var dX = x - centerX;
var dY = y - centerY;
if(dX * dX + dY * dY < (radius * radius))
{
c = ch;
}
Console.Write(c);
}
}
}
I have a draw function
public void drawBoard(Graphics g) {
int height = this.getHeight();
int width = this.getWidth();
int dx = width / 7;
int dy = height / 6;
for (int x = 0, row = 0; x <= width && row < gameboard.length; row++, x += dx) {
for (int col = 0, y = 0; y <= height&& col < gameboard[0].length; y += dy, col++) {
if (gameboard[row][col] == 0) {
g.setColor(Color.GRAY);
g.fillOval(y, x, dy, dx);
} else if (gameboard[row][col] == 1) {
g.setColor(Color.RED);
g.fillOval(y, x, dy, dx);
} else if(gameboard[row][col] == 1){
g.setColor(Color.BLACK);
g.fillOval(y, x, dy, dx);
} else if(gameboard[row][col]==3){
}else if(gameboard[row][col]==4){
}else if(gameboard[row][col]==5){
}else if(gameboard[row][col]==6){
}else if(gameboard[row][col]==7){
}else if(gameboard[row][col]==8){
}else if(gameboard[row][col]==9){
}
}
}
}
However for when gameboard[row][col]=3,4,...9 I want it to change that slot into a picture downloaded from the web. How do I do that?
I would prefer to do it without a URL definition and simply a get Document like thing in html where I have the photos saved in a file
First, you need to get your image as a BufferedImage. I suggest using the ImageIO class:
String imageFileName = "myTestFile.jpg"
BufferedImage img = ImageIO.read(((new File(imageFileName)).toURI()).toURL());
Next, you want to draw your image using the Graphics.drawImage() API. Your comment indicates that you think you'll need to scale the image, so use the appropriate drawImage method to do that. Using your Graphics object g from your code above, this might look like::
int oldWidth = img.getWidth();
int oldHeight = img.getHeight();
int newWidth = 10; //You decide this...
int newHeight = 10; //You decide this too...
g.drawImage(img, 0, 0, oldWidth, newWidth, 0, 0, newWidth, newHeight, null);
Oracle themselves have an applet which demonstrates the code for this approach, along with a number of other common operations you might want to do on images in their ImageDrawingApplet.java code
I was given an assignment and have been able to complete it, but I feel there must be a easier way to complete it.
I was tasked to draw 60 vertical bars with a width of 5 and random heights.
public void paintComponent( Graphics g )
{
super.paintComponent( g );
g.setColor( color );
int width = getWidth();
int height = getHeight();
int x, h;
// bar with a width of 5 and random heights
h = rd.nextInt(height); //random height
x = 50;
g.drawLine( x, height, x, height-h ); //Bar 1
g.drawLine( x+1, height, x+1, height-h );
g.drawLine( x+2, height, x+2, height-h );
g.drawLine( x+3, height, x+3, height-h );
g.drawLine( x+4, height, x+4, height-h );
g.drawLine( x+6, height, x+6, height-h -12 ); // Bar 2
g.drawLine( x+7, height, x+7, height-h -12 );
g.drawLine( x+8, height, x+8, height-h -12 );
g.drawLine( x+9, height, x+9, height-h -12 );
g.drawLine( x+10, height, x+10, height-h -12);
What I have done is just repeat this for all 60 bars and just change the offset at the end of height-h +/- * and left a space of 1 between bars
This seems like a very long way to do this. Any suggestions on how to implement this without repeating it 60 times.
Edit: Added an image of the final project.
Here is the finished look ![1]
[1]: http://i.stack.imgur.com/3ivpM.png
Looking at the other answers, no one states the obvious:
To draw 60 bars, you don't need to draw more than 60 items (certainly not 60x5=300 lines).
Your options:
draw the bars as filled rectangles
draw the bars as lines with a width of 5
Also the bar values should not be calculated while painting, they're supposed to be the data model.
public class Bars extends JPanel {
private double[] barValues;
private final static int BAR_WIDTH = 5;
private final static int BAR_GAP = 3;
public Bars () {
barValues = new double[60];
for (int i = 0; i < barValues.length; i++) {
barValues[i] = Math.random();
}
}
...
}
Painting using rectangles:
#Override
protected void paintComponent (Graphics g) {
Dimension size = getSize();
g.setColor(Color.white);
g.fillRect(0, 0, size.width, size.height);
g.setColor(new Color(0x445566));
for (int i = 0; i < barValues.length; i++) {
int h = (int) Math.round(barValues[i] * size.height);
int x = (i * (BAR_WIDTH + BAR_GAP));
int y = size.height - 1 - h;
int w = BAR_WIDTH;
g.fillRect(x, y, w, h);
}
}
Painting using lines of width 5:
#Override
protected void paintComponent (Graphics g) {
Dimension size = getSize();
g.setColor(Color.white);
g.fillRect(0, 0, size.width, size.height);
g.setColor(new Color(0x445566));
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(5, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
for (int i = 0; i < barValues.length; i++) {
int h = (int) Math.round(barValues[i] * size.height);
int x = (i * (BAR_WIDTH + BAR_GAP)) + BAR_WIDTH / 2;
int y = size.height - 1 - h;
g.drawLine(x, y, x, y + h);
}
}
You could use a for loop with %
for(int i = 0, int j = 0 ; i < 360 ; i++ ) {
if(i % 5 != 0 ) {
g.drawLine( x+i, height, x+i, height-h - j);
}
if(i % 6 = 0)
j = j - 12;
}
I think that's right for what you want. I have made some assumptions:
You skip every 6th line to leave a space
You increase j by negative 12 every second line
why you don't use for loop and bunch of if statements!
for(int i = 0; i < 60; i++) {
if( i < 5) {
}
if( i > 5 && i < 10) {
}
// etc..
}
This is the second try :P
public void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
System.out.println("getWidth = " + getWidth());
System.out.println("getHeight = " + getHeight());
Random rd = new Random();
int x = 50;
for (int i = 0; i <= 60; i++) {
int fisrt = (i / 12) * 12;
for (int j = 0; j < 12; j++) {
int h = rd.nextInt(height); // random height
g.drawLine(x + j, height, x + j, height - h - fisrt);
}
}
}
This is a great example of when to use a loop. To draw the first five lines you need something like this.
public void drawLines(int x, int height, int h, int j){
for(int i = 0; i < 5; i++){
g.drawLine(x + i, height, x + i, height - h - j);
}
}
However, this is not complete because you have to do this multiple times. just use another for loop.
for(int i = 0; i < 12, i++){
drawLines(x + i * 5, height, h, i * 12);
}
What you saw but didn't know it
You saw a pattern of repeating code. In time and probably after an algorithm class you should be able to pre-predict patterns, some are obvious some are not. This is where reasoning, deductive and math skills come in. Which goes in the order of:
I am repeating myself...
Why am I repeating this
Is this is a basic pattern?
If I am not seeing a basic pattern...can this code be broken down further?
What is changing increase/decreasing on each same line of code
What coding idiom (loop, do-while,collection etc) do I know that best deals with this
This is also why keeping code methods short and to the point allows you to see the above more clearly.
But more important before you code: design your objects beforehand. This will allow you to solve 99 problems before you even have to deal with the coding aspect.
A good design can work in any code of that type (in this case OO/object orientated).
(Some might argue to keep the second loop in the code below to its separate method to keep it clean, readable and allow you to reuse it again.)
Your Solution
Create a method to get your barWidth and this should be your whole paintComponent method. Everything is commented and all variables are clearly defined in what they do, but if you require any help understanding any part do say.
I am not sure why you have rd as a global field.
public void paintComponent( Graphics g ) {
// Carry out super first
super.paintComponent( g );
// Set all field types at start
int totalWidth, totalHeight, barHeight, barWidth, totalBarsRequired;
// Set all constant fields
barWidth = 5; // THE BAR WIDTH IS SET HERE (Create a method)
// Set all method fields
totalWidth = getWidth();
totalHeight = getHeight();
// No need to set the bars as we can calculate them from the bar width
totalBarsRequired = (int) totalWidth / barWidth;
// Look over all the bars required
for( int barNumber = 0 ; barNumber < totalBarsRequired ; barNumber++ ) {
// Set a new random height each bar
barHeight = rd.nextInt( totalHeight );
// Create the lines and loop until the barWidth has been met
for (int barLineNumber = 0 ; barLineNumber < barWidth ; barLineNumber++ ) {
g.drawLine( (barNumber * barWidth) + barLineNumber, barHeight, (barNumber * barWidth) + barLineNumber, barHeight );
}
}
}
I've searched for some time already but haven't been able to find an answer to my question.
First I'll show two comparison pictures:
Method 1:
method 1 http://img713.imageshack.us/img713/3558/tcg6.jpg
Method 2:
method 2 http://img716.imageshack.us/img716/2755/tcg7.jpg
Method 1 has never given me any trouble, but I recently found out that it simply takes too long, and method 2 fixed that.
Code for method 1:
private void drawDefaultOrientation() {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int dx = Math.min(x, width - 1 - x);
int dy = Math.min(y, height - 1 - y);
if (dx < borderSize || dy < borderSize) {
inBorder(dx, dy);
}
else {
outBorder(dx, dy);
}
bufferedImage.setRGB(xOffset + x, yOffset + y, color.getRGB());
}
}
}
Code for method 2:
private void drawDefaultOrientation() {
DataBufferInt buffer = (DataBufferInt)bufferedImage.getRaster().getDataBuffer();
int[] pixelArray = buffer.getData();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int dx = Math.min(x, width - 1 - x);
int dy = Math.min(y, height - 1 - y);
if (dx < borderSize || dy < borderSize) {
inBorder(dx, dy);
}
else {
outBorder(dx, dy);
}
pixelArray[(xOffset + x) + ((yOffset + y) * bufferedImage.getWidth())] = color.getRGB();
}
}
}
Please also note that the inBorder(dx, dy); and outBorder(dx, dy); set the color variable to a color with a Red, Green, Blue and Alpha value.
Callee code:
new CustomRectangle(bufferedImage, 220, 90, 15, 245, 5, defaultOrientation) {
#Override
public void inBorder(final int dx, final int dy) {
setColor(new Color(red, green, blue, 255 - Math.min(dx, dy)));
}
#Override
public void outBorder(final int dx, final int dy) {
setColor(new Color(red, green, blue, 128 - Math.min(dx, dy)));
}
}.draw();
I am really lost as to why the color difference is here.
I really hope anyone out there can help me. First I thought it had to do with the Alpha values, but as seen the alpha variaton still exists with method 2.
Regards.
I'd suggest, for "simple" thing (including boxes, shapes, gradients, and a lot more), you use directly the Java2D API. It will be both more efficient and simpler to write.
For example to fill a rectangle in your image with a color:
public void rectangle(Color color, float x1, float y1, float w, float h) {
Graphics2D g = bufferedImage.createGraphics();
g.setColor(color);
g.fill(new Rectangle2D.Float(x1, y1, w, h));
g.dispose(); // optional but releases the resource earlier
}
You can also use "g" to draw as much things as you need to do.