3

I have an circle in my java program. Its just a simple circle like this:

private BufferedImage img;
Graphics2D g = img.createGraphics();
g.fill(new Area(new Ellipse2D.Double(x, y, diam, diam)));

Now i want to insert an image into the circle. I know how i can create an image with the drawImage like this:

image = Toolkit.getDefaultToolkit().getImage(url);
g2.drawImage(image, x, y, WIDTH, HEIGHT, null);

But how can i create an image inside a circle?

Edit: I tried to do the clipping as ControlAltDel suggested but it is not working and i dont know why. My code is bellow. My program works fine with just simple yellow circles. In the file Pang.java i tried to replace the line: g.fill(bubbles[i].getBubbleArea()); by: Image image = new ImageIcon("bubble.png").getImage(); g.clip(new Ellipse2D.Double(100, 100, 50, 5)); g.drawImage(image, 150, 180, null); but its not working and i donst get any errors. What am i doing wrong?

Pang.java:

package pang.gui;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.awt.TexturePaint;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

class ShapeCollision {

 private BufferedImage img;
 private Area limits;

 private int w = 800;// width of the game window
 private int h = 400;// heigth of the game window

 // private Bubble bubble = new Bubble(w, h);
 private Bubble[] bubbles = new Bubble[4];



 ShapeCollision() {

  img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
  /**
   * global image of the game shown in the window. This image will be
   * added to the JLabel (imageLabel)
   */

  final JLabel imageLabel = new JLabel(new ImageIcon(img));
  /**
   * JLabel that contains the global image of the game
   */



  for (int i = 0; i < bubbles.length; i++) {
   bubbles[i] = new Bubble(40 + i * 80, 40 + i * 80,i);
  }

  limits = new Area(new Rectangle(0, 0, w, h));
  /**
   * game limits or painted area
   */

  ActionListener animate = new ActionListener() {

   @Override
   public void actionPerformed(ActionEvent e) {
    animate();
    imageLabel.repaint();
   }
  };
  Timer timer = new Timer(50, animate);
  /**
   * Repaint rate
   */

  timer.start();
  JOptionPane.showMessageDialog(null, imageLabel);
  timer.stop();
 }

 public void animate() {
  Graphics2D g = img.createGraphics();
  /**
   * Creates a Graphics2D, which can be used to draw into this
   * BufferedImage (img).
   */

  g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);
  /**
   * removes edges from the shape, makes rounder objects
   */

  g.setColor(Color.BLUE);
  /**
   * color of the game windows background
   */

  g.fillRect(0, 0, img.getWidth(), img.getHeight());
  /**
   * size of the Graphics2D object (g). In this case the game window is
   * filled
   */

  for (Bubble bubble : bubbles) {
   bubble.IncrementPos();
   bubbleWallCollision(bubble);

  }

  for (Bubble bubble : bubbles) {
   detectBubblesCollisions(bubble);
  }

  g.setColor(Color.YELLOW);

  for (int i = 0; i < bubbles.length; i++) {
//Image image = new ImageIcon("bubble.png").getImage();
//g.clip(new Ellipse2D.Double(100, 100, 50,
//  5));
//g.drawImage(image, 150, 180, null);
   g.fill(bubbles[i].getBubbleArea());
   /**
    * the bubble is filled *after* the obstacles, so the bubble is
    * allways shown. If the bubble is on top of an abstacle that
    * obstacle is covered by the bubble
    */
  }

  g.dispose();
 }



 private void detectBubblesCollisions(Bubble bubble1) {
  for (Bubble bubble : bubbles) {
   if (bubble1 != bubble) {
    if (bubble1.getX() + bubble1.getBubbleDiam() / 2
      + bubble.getBubbleDiam() / 2 > bubble.getX()
      && bubble1.getX() < bubble.getX()
        + bubble1.getBubbleDiam() / 2
        + bubble.getBubbleDiam() / 2
      && bubble1.getY() + bubble1.getBubbleDiam() / 2
        + bubble.getBubbleDiam() / 2 > bubble.getY()
      && bubble1.getY() < bubble1.getY()
        + bubble1.getBubbleDiam() / 2
        + bubble.getBubbleDiam() / 2) {
     if (PangUtilities.areasDistance(bubble1, bubble) < bubble1
       .getBubbleDiam() / 2 + bubble.getBubbleDiam() / 2) {
      calculateNewVelocities(bubble1, bubble);
     }
    }
   }

  }

 }

 private void calculateNewVelocities(Bubble bubble1, Bubble bubble) {
  double mass1 = bubble1.getBubbleDiam()/2;
  double mass2 = bubble.getBubbleDiam()/2;
  double velX1 = bubble1.get_xDelta();
  double velX2 = bubble.get_xDelta();
  double velY1 = bubble1.get_yDelta();
  double velY2 = bubble.get_yDelta();
    
  double newVelX1 = (velX1 * (mass1 - mass2) + (2 * mass2 * velX2)) / (mass1 + mass2);
  double newVelX2 = (velX2 * (mass2 - mass1) + (2 * mass1 * velX1)) / (mass1 + mass2);
  double newVelY1 = (velY1 * (mass1 - mass2) + (2 * mass2 * velY2)) / (mass1 + mass2);
  double newVelY2 = (velY2 * (mass2 - mass1) + (2 * mass1 * velY1)) / (mass1 + mass2);
 
 
 bubble1.set_xDelta(newVelX1);
 
 bubble.set_xDelta(newVelX2);
bubble1.set_yDelta(newVelY1);
 
 bubble.set_yDelta(newVelY2);
    
    bubble1.setX(bubble1.getX() + newVelX1);
    bubble1.setY(bubble1.getY() + newVelY1);
 
    bubble.setX(bubble.getX() + newVelX2);
    bubble.setY(bubble.getY() + newVelY2);


 }

 private void bubbleWallCollision(Bubble bubble) {
  if (bubble.getX() + bubble.getBubbleDiam()/2 >= w
    && bubble.get_xDelta() > 0)
   bubble.invert_xDelta();
  if (bubble.getX()-bubble.getBubbleDiam()/2 <= 0 && bubble.get_xDelta() < 0)
   bubble.invert_xDelta();
  if (bubble.getY() + bubble.getBubbleDiam()/2 >= h
    && bubble.get_yDelta() > 0)
   bubble.invert_yDelta();
  if (bubble.getY()-bubble.getBubbleDiam()/2 <= 0 && bubble.get_yDelta() < 0)
   bubble.invert_yDelta();

 }

 public static void main(String[] args) {
  Runnable r = new Runnable() {

   @Override
   public void run() {
    new ShapeCollision();
   }
  };
  SwingUtilities.invokeLater(r);
 }
}

Bubble.java:

package pang.gui;

import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;

public class Bubble {
 private Area bubbleArea = new Area();
 private double bubbleDiam = 20, bubbleSpeed = 2;// bubble diameter
private Shape shape;
 private double x;
 private double y;

 private int initialDirectionX, initialDirectionY;
 private double xDelta = bubbleSpeed;// bubble move increments
 private double yDelta = bubbleSpeed;// bubble move increments

 public Bubble(int x, int y,int i) {

  this.x = x;// Bubble position
  this.y = y;// Bubble position
  this.bubbleDiam *=i+1;
  System.out.println(bubbleDiam);

  genDirection();

 }

 public void IncrementPos() {
  x += xDelta;// new position of the bubble
  y += yDelta;// new position of the bubble
  this.bubbleArea = new Area(new Ellipse2D.Double(x-bubbleDiam/2, y-bubbleDiam/2, bubbleDiam,
    bubbleDiam));// bubble area definition
  shape=new Ellipse2D.Double(x-bubbleDiam/2, y-bubbleDiam/2, bubbleDiam,
    bubbleDiam);
 }

 
 
 public Shape getShape() {
  return shape;
 }

 public void setX(double d) {
  this.x = d;
 }

 public void setY(double d) {
  this.y = d;
 }

 public Area getBubbleArea() {
  return bubbleArea;
 }

 public double getBubbleDiam() {
  return bubbleDiam;
 }

 public double get_xDelta() {
  return xDelta;
 }

 public double get_yDelta() {
  return yDelta;
 }

 public void set_xDelta(double d) {
  this.xDelta = d;
 }

 public void set_yDelta(double d) {
  this.yDelta = d;
 }

 public void invert_yDelta() {
  yDelta *= -1;

 }

 public void invert_xDelta() {
  xDelta *= -1;

 }

 public double getX() {
  return x;
 }

 public double getY() {
  return y;
 }

 private void genDirection() {
  do {
   initialDirectionX = PangUtilities.genRandomInt(-3, 3);
  } while (initialDirectionX == 0);

  do {
   initialDirectionY = PangUtilities.genRandomInt(-3, 3);
  } while (initialDirectionX == initialDirectionY
    || initialDirectionY == 0);

  xDelta *= initialDirectionX;
  yDelta *= initialDirectionY;
 }

}

PangUtilities.java:

package pang.gui;

import java.util.Random;

public class PangUtilities {

 public static int genRandomInt(int min, int max) {

  Random rand = new Random();

  return min + rand.nextInt((max - min) + 1);

 }

 public static double areasDistance(Bubble b1, Bubble b2) {

  double distance = Math
    .sqrt(((b1.getX() - b2.getX()) * (b1.getX() - b2.getX()))
      + ((b1.getY() - b2.getY()) * (b1.getY() - b2.getY())));
  return distance;
 }

}
user2880113
  • 345
  • 1
  • 5
  • 13

1 Answers1

1

There are two ways to do this

  1. (Easier) set the clipping on your Graphics object with your circle Shape
  2. Turn your Image into a TexturePaint and then do

.

Graphics2D g = ...;
g.setPaint(myImagePaint);
g.fill(yourCircle);
mKorbel
  • 109,525
  • 20
  • 134
  • 319
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
  • Is the cliping something like this?: Image image = new ImageIcon("image.png").getImage(); g.clip(new Ellipse2D.Double(x, y, d, d)); g.drawImage(image, x, y, null); – user2880113 May 19 '15 at 20:32
  • Yes, that's how you do it, though I'd recommend you keep your clipping Shape around, rather than making a new one each time – ControlAltDel May 20 '15 at 01:33