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
Well since you folks helped me a lot with my last project, I thought I might find some assistance with the current one :)
The project has us practicing recursion and objects (just started learning about the latter). So we first create a "BasicStar", later a "Snowflake", then comes the "SuperSnowflake" and finally the dreaded "KochCurve".
So I the "BasicStar" was quite easy, and now the idea of the "Snowflake" is to recursively draw "BasicStar"s with smaller radiuses. I have uploaded three images (basic star, which I did successfully, snowflake the way it should be, and my snowflake) so it's easy to understand what I mean. My recursive method draws something very different, and I have no idea what I'm doing wrong. Any help would be great.
Thanks!
(P.S. The Main and Painter classes were made by the university faculty so even if there are things to improve there it won't be relevant. The rest was written by myself)
Main:
package recursion;
import java.util.Scanner;
/*
* the class main get from the user the shape he wish to draw,
* and call the drew method of the desired shape .
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter the number of the shape you wish to draw:\n" +
" 1-example\n" +
" 2-BasicStar\n" +
" 3-Snowflake\n" +
" 4-SuperSnowflake\n" +
" 5-KochCurve\n" +
" 6-KochSnowflake\n");
int shape = sc.nextInt();
// chooses which shape to draw based on the number received
switch(shape){
/*
* An example given to you so you can see how the painted works.
* This example opens a frame, and draws a red line.
*/
case 1:
drawExample();
break;
case 2:
drawBasicStar();
break;
case 3:
drawSnowflake();
break;
case 4:
drawSuperSnowflake();
break;
case 5:
drawKochCurve();
break;
case 6:
drawKochSnowflake();
break;
default: System.out.println("invalid shape");
}
sc.close();
}
// Draw the example line
public static void drawExample(){
Painter.draw("example");
}
// Draw a BasicStar
public static void drawBasicStar(){
Painter.draw("BasicStar");
}
// Draw a Snowflake
public static void drawSnowflake(){
Painter.draw("Snowflake");
}
// Draw a SuperSnowflake
public static void drawSuperSnowflake(){
Painter.draw("SuperSnowflake");
}
// Draw a KochCurve
public static void drawKochCurve(){
Painter.draw("KochCurve");
}
// Draw a KochSnowflake
public static void drawKochSnowflake(){
Painter.draw("KochSnowflake");
}
}
Painter:
package recursion;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
/*
* open a frame named aShape and drew the given shape
*/
public class Painter extends Component {
private static final long serialVersionUID = 1L;
private static int SIZE = 600;
private static Painter painter;
private static Graphics g;
private static String shape = null;
// Create a frame and display it
public static void draw(String aShape) {
shape = aShape;
JFrame frame = new JFrame(shape);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
painter = new Painter();
frame.add(painter, null);
frame.pack();
frame.setVisible(true);
}
// returns the Frame's width
public static int getFrameWidth () {
return painter.getSize().width;
}
// returns the Frame's height
public static int getFrameHeight () {
return painter.getSize().height;
}
// changes the color of the lines to be drawn
public static void setColor (String color) {
if (color.equals("red")){
g.setColor(Color.red);
}
else if (color.equals("blue")){
g.setColor(Color.blue);
}
else if (color.equals("green")){
g.setColor(Color.green);
}
}
public static void drawLine (Pixel p1, Pixel p2) {
drawLine((int)Math.round(p1.getX()),(int)Math.round(p1.getY()),(int)Math.round(p2.getX()),(int)Math.round(p2.getY()));
}
// Draw a line on the frame
public static void drawLine (int x1, int y1, int x2, int y2) {
g.drawLine(x1, getFrameHeight()-y1, x2, getFrameHeight()-y2);
}
// Set the default size of the window frame to SIZE*SIZE pixels
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
// paint the frame - draw the shape given (call the draw method in that shape object)
public void paint(Graphics g) {
Painter.g = g;
try{
Object myShape = (Class.forName("recursion." + shape)).newInstance();
Object [] objs = null;
Class [] classes = null;
(Class.forName("recursion." + shape)).getMethod("draw", classes).invoke(myShape, objs);
}
catch(Exception e)
{
System.out.println("Can't handle shape " + shape);
System.out.println(e.toString());
System.out.println(e.getCause());
}
}
}
Pixel:
package recursion;
public class Pixel {
private double x;
private double y;
public Pixel(){
x = 0;
y = 0;
}
public Pixel(double x, double y){
this.x = x;
this.y = y;
}
public Pixel(Pixel center){
this();
if(center != null){
this.x = center.x;
this.y = center.y;
}
}
public double getX(){
return x;
}
public double getY(){
return y;
}
public void translate(Pixel p){
this.x = this.x + p.x;
this.y = this.y + p.y;
}
public void rotateRelativeToAxesOrigin(double theta){
double tempX = this.x;
double tempY = this.y;
this.x = ((tempX)*(Math.cos(theta)) - ((tempY)*(Math.sin(theta))));
this.y = ((tempX)*(Math.sin(theta)) - ((tempY)*(Math.cos(theta))));
}
public void rotateRelativeToPixel(Pixel p1, double theta){
double tempX = this.x;
double tempY = this.y;
Pixel translatedPixel = new Pixel(tempX-p1.getX(), tempY-p1.getY());
translatedPixel.rotateRelativeToAxesOrigin(theta);
this.x = translatedPixel.getX() + p1.getX();
this.y = translatedPixel.getY() + p1.getY();
}
}
BasicStar:
package recursion;
public class BasicStar {
private Pixel center;
private double radius;
public BasicStar(){
double height = Painter.getFrameHeight()/2;
double width = Painter.getFrameWidth()/2;
this.center = new Pixel (width, height);
double maxRadius = Math.min(width, height)/2;
this.radius = maxRadius/4;
}
public BasicStar(Pixel center, double radius){
this.center = new Pixel(center);
this.radius = radius;
}
public Pixel getCenter(){
return new Pixel(center);
}
public double getRadius(){
return this.radius;
}
public void draw(){
Pixel begin = new Pixel(this.center);
Pixel end = new Pixel(center.getX() + getRadius(), center.getY());
Painter.drawLine(begin, end);
end.rotateRelativeToPixel(center, (2*Math.PI)/6);
Painter.drawLine(begin, end);
end = new Pixel(center.getX() + getRadius(), center.getY());
end.rotateRelativeToPixel(center, (4*Math.PI)/6);
Painter.drawLine(begin, end);
end = new Pixel(center.getX() + getRadius(), center.getY());
end.rotateRelativeToPixel(center, (6*Math.PI)/6);
Painter.drawLine(begin, end);
end = new Pixel(center.getX() + getRadius(), center.getY());
end.rotateRelativeToPixel(center, (8*Math.PI)/6);
Painter.drawLine(begin, end);
end = new Pixel(center.getX() + getRadius(), center.getY());
end.rotateRelativeToPixel(center, (10*Math.PI)/6);
Painter.drawLine(begin, end);
}
}
Snowflake:
package recursion;
public class Snowflake {
private BasicStar basic;
private int depth;
public Snowflake(){
double height = Painter.getFrameHeight()/2;
double width = Painter.getFrameWidth()/2;
Pixel center = new Pixel (width, height);
double maxRadius = Math.min(width, height)/2;
double radius = maxRadius/4;
this.basic = new BasicStar(center, radius);
this.depth = 2;
}
public Snowflake(BasicStar basic, int depth){
this();
if(basic!=null){
this.basic = basic;
this.depth = depth;
}
}
public int getDepth(){
return this.depth;
}
public BasicStar getBasic(){
return this.basic;
}
public double getRadius(BasicStar basic){
return this.basic.getRadius();
}
public Pixel getBasicCenter(BasicStar basic){
return this.basic.getCenter();
}
public void draw(){
draw(this.depth, basic.getCenter(), basic.getRadius());
}
private void draw(int depth, Pixel center, double radius){
BasicStar basic = new BasicStar(center, radius);
if(depth==1){
basic.draw();
}
else{
Pixel p = new Pixel(center.getX() + radius, center.getY());
draw(depth - 1, p, (radius/3));
for(int i=0; i<6; i=i+1){
p.rotateRelativeToPixel(center, (2*Math.PI)/6);
BasicStar temp = new BasicStar(p, radius/3);
temp.draw();
}
}
}
}
This looks overly complicated to me. To be honest, I did not read all your code, but you can create a simple recursive function for drawing a snowflake just like this:
public void drawSnowflake(Graphics g, int x, int y, int size, int level) {
for (int a = 0; a < 360; a += 60) {
double rad = a * Math.PI / 180;
int x2 = (int) (x + Math.cos(rad) * size);
int y2 = (int) (y + Math.sin(rad) * size);
g.drawLine(x, y, x2, y2);
if (level > 0) {
drawSnowflake(g, x2, y2, size/3, level-1);
}
}
}
What this code does is: It draws the lines of a star using basic trigonometry (don't forget to convert angles to radians!), and then calls itself with a smaller size and level for the positions at the ends of the spikes. Embedding this into an actual GUI is left as an excercise to the reader.
Related
Before you read ahead this question is for my homework so it will be specific.
I am writing some code that uses polymorphism to display the properties of a rectangle (ie, x, y, height...). The code uses inheritance and polymorphism to achieve the results. Everything like the width and topleftX point is being determined using an algorithm that picks a random integer from a specified range. How I tried to fix the problem is to write a getWidth() and getLength() method to the rectangle class. I put in a super(); for the other class that gets the X and Y coordinates.
The problem that I am having is that I am unsure of how to access the classes that will give me the width and height of the rectangle. Inside of the methods that I have written the super() displays an error and it says "(x,y) cannot be applied to ()" which I am unsure of what it means. I assume that the values are private and I cannot access them, but in the class with the implementation, there are no private instances, so I am confused.
This is my code below:
public GeometricShapeTester(){
shapes = new GeometricShape[20];
Random rand = new Random();
int option;
final int COORD = 50;
final int LENGTH1 = 50;
final int LENGTH2 = 100;
for(int i=0; i<shapes.length; i++){
option=rand.nextInt(4);
switch(option){
case 0:
shapes[i]= new Rectangle(
rand.nextInt(COORD),
rand.nextInt(COORD),
rand.nextInt(LENGTH2),
rand.nextInt(LENGTH2));
break;
case 1:
shapes[i]= new Square(
rand.nextInt(COORD),
rand.nextInt(COORD),
rand.nextInt(LENGTH2));
break;
case 2:
shapes[i]= new Oval(
rand.nextInt(COORD),
rand.nextInt(COORD),
rand.nextInt(LENGTH1),
rand.nextInt(LENGTH2));
break;
case 3:
shapes[i]= new Circle(
rand.nextInt(COORD),
rand.nextInt(COORD),
rand.nextInt(LENGTH1));
}
}
}
public GeometricShape[] getShapes(){
return shapes;
}
}
abstract class GeometricShape{
private int x;
private int y;
public GeometricShape(int x,int y){
this.x = x;
this.y = y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
abstract public double getArea();
abstract public String toString();
}
class Rectangle extends GeometricShape{
public Rectangle(int x, int y, int nextInt, int nextInt1) {
super();
}
public getWidth(){
super();
}
public getLength(){
super();
}
#Override
public double getArea() {
return 0;
}
#Override
public String toString() {
return "Rectangle: [x:" + getX() + ", y:" + getY() + ", width: + " + getWidth() + " height: " + getHeight() + "]";
}
// body
}
I asked this question on Math.se a few days ago, and got the following answer in pseudocode:
Function RandomCircleInside(centerX, centerY, radius):
Let newRadius = radius * Random()
Let radians = 2.0 * 3.14159265358979323846 * Random()
Let deviation = (radius - newRadius) * Sqrt(Random())
Let newX = centerX + deviation * Cos(radians)
Let newY = centerY + deviation * Sin(radians)
Return (newX, newY, newRadius)
End Function
I changed the pseudocode to Java and added my own changes to fit my needs. The new code looks like this:
Circle createNewCircle(int centerX, int centerY, int radius, int newR, Color newColor) {
int newRadius = radius * Random();
double radians = 2.0 * 3.141592653589793 * Random();
double deviation = (radius - newRadius) * Math.sqrt(Random());
System.out.println(radius + " - " + newRadius + " * sqrt(0 or 1) = " + (radius-newRadius) + " * (0 or 1) = " + deviation);
double newX = centerX + deviation * Math.cos(radians);
System.out.println(centerX + " + " + deviation + " * cos(" + radians + ") = " + (centerX + deviation) + " * " + Math.cos(radians));
double newY = centerY + deviation * Math.sin(radians);
int newCirX = (int) newX;
int newCirY = (int) newY;
Circle newCir = new Circle(newCirX, newCirY, newR*2, newR*2, newR, newColor, true);
return newCir;
}
The code itself is supposed to create a new Circle inside of a preexisting one. I created a circle class that looks like this:
import java.awt.Color;
import java.awt.Graphics;
public class Circle {
public int X, Y, Width, Height, radius;
public Color color;
public boolean toFill;
public Circle(int x, int y, int width, int height, int radius, Color color, boolean fill) {
X = x;
Y = y;
Width = width;
Height = height;
this.radius = radius;
this.color = color;
toFill = fill;
}
public void render(Graphics g) {
g.setColor(color);
for(int i=-5; i<5; i++) {
if(toFill) {
g.fillOval(X+i, Y+i, Width-i, Height-i);
} else {
g.drawOval(X+i, Y+i, Width-i, Height-i);
}
}
}
public boolean contains(Circle pBound) {
int pBoundCenterX = pBound.X+pBound.radius;
int cirCenterX = X+radius;
int diffBetweenCentersX = Math.abs(pBoundCenterX-cirCenterX);
int pBoundCenterY = pBound.Y+pBound.radius;
int cirCenterY = Y+radius;
int diffBetweenCentersY = Math.abs(pBoundCenterY-cirCenterY);
if(diffBetweenCentersX<= (pBound.radius+radius) && diffBetweenCentersX>=Math.abs(pBound.radius-radius)) { // X
if(diffBetweenCentersY>=Math.abs(pBound.radius-radius)) { // Y
return true;
}
}
return false;
}
public int getX() {
return X;
}
public int getWidth() {
return Width;
}
public int getRadius() {
return radius;
}
public void setWidth(int width) {
Width = width;
}
public int getHeight() {
return Height;
}
public void setHeight(int height) {
Height = height;
}
public void setX(int x) {
X = x;
}
public int getY() {
return Y;
}
public void setY(int y) {
Y = y;
}
}
My way of creating the new circle is this:
if(secInGame==timesForCircle[X] && !hasChanged) { // circle 2
Circle cir1 = cir;
cir = createNewCircle(cir1.X+(cir1.Width/2), cir1.Y+(cir1.Height/2), cir1.getRadius(), 135, Color.cyan);
hasChanged = true;
circleOn++;
circ++;
}
Where cir1 is the preexisting Circle and cir is the new circle.
Is there anything I didn't code correctly? I've tried a few different variations, but they all give the same result.
Before I implemented the pseudocode, my circles looked like this:
but now it looks like this:
All of my code can be found on github at: link
I think there are several issues in your code.
1. First of all it is not clear why your Circle has radius, Width and Height. For a circle all 3 things should be the same. Also your render in case toFill is true looks strange. Here is a simplified version (note: I didn't compile it so there might be some bugs):
public class Circle {
public int X, Y, radius;
public Color color;
public boolean toFill;
public Circle(int x, int y, int radius, Color color, boolean fill) {
X = x;
Y = y;
this.radius = radius;
this.color = color;
toFill = fill;
}
public void render(Graphics g) {
g.setColor(color);
final int r2 = 2*radius;
if(toFill) {
g.fillOval(X, Y, r2, r2);
}
else {
for(int i=-5; i<5; i++) {
g.drawOval(X+i, Y+i, r2-i, r2-i);
}
}
}
public boolean contains(Circle pBound) {
int pBoundCenterX = pBound.X+pBound.radius;
int cirCenterX = X+radius;
int diffBetweenCentersX = Math.abs(pBoundCenterX-cirCenterX);
int pBoundCenterY = pBound.Y+pBound.radius;
int cirCenterY = Y+radius;
int diffBetweenCentersY = Math.abs(pBoundCenterY-cirCenterY);
if(diffBetweenCentersX<= (pBound.radius+radius) && diffBetweenCentersX>=Math.abs(pBound.radius-radius)) { // X
if(diffBetweenCentersY>=Math.abs(pBound.radius-radius)) { // Y
return true;
}
}
return false;
}
public int getX() {
return X;
}
public int getRadius() {
return radius;
}
public void setX(int x) {
X = x;
}
public int getY() {
return Y;
}
public void setY(int y) {
Y = y;
}
}
I didn't check your code, but I'd consider as a good practice:
renaming x and y into leftX and topY to avoid confusion with centerX/centerY meaning. Or change meaning to more typical center one.
declaring all your fields as private (see encapsulation);
declaring all your fields as final and remove all the setXyz methods (see immutability)
2. I don't understand why your createNewCircle has newR parameter and at the same time you generate a random newRadius in the first line. One of these definitely should be removed. Given that the parameter is always a constant 135 I think it should be removed.
3. Now I believe the main bug in your translation is in the lines
int newCirX = (int) newX;
int newCirY = (int) newY;
It probably should be something like
int newCirX = (int) newX - newRadius;
int newCirY = (int) newY - newRadius;
It looks like you messed with center vs top-left. Actually I think the fact that you made such a bug is an argument that supports renaming x and y I suggested in item #1.
Anyone has a good algorithm for how to get a smooth but predictable movement from point a -> b in 2D in any language?
I need to have one function setting the velocity each frame:
function GetVel(current_pos : Vector2, dest_pos : Vector2, current_vel : Vector2)
{
var new_vel : Vector2d;
.......
return new_vel;
}
and a corresponding:
function GetDestTime(current_pos : Vector2, dest_pos : Vector2, current_vel : Vector2 )
{
var duration : float;
.......
return duration;
}
Simply using acceleration leads up to lots of sliding so some good smoothDamp algorithm that can be predicted the exact dest time is what I need.
Any ideas?
Let's assume v(0) = 0 and v(T) = 0 and, v(t) is a quadratic function which the maximum value at t = T/2.
Accordingly, we can assume the form,
Since the point moves L within T seconds, integrating v(t) from 0 to T must give L. So, we can get another equation,
Solving these equations gives,
Using these a and b, you can compute the current velocity.
It is rather long, but I made a Java toy to realize this. Please check it!
import java.awt.*;
import javax.swing.*;
public class MovePoint extends Canvas implements Runnable {
public static void main(String... args) {
Thread thread = new Thread(new MovePoint());
thread.start();
}
private static final int WIDTH = 500;
private static final int HEIGHT = 500;
public MovePoint() {
super();
this.setBackground(Color.WHITE);
this.setForeground(Color.BLACK);
this.setSize(WIDTH, HEIGHT);
JFrame f = new JFrame("Move Point");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setVisible(true);
}
private Point V;
private Point S = new Point(50, 50);
private Point E = new Point(450, 450);
private double duration = 5.0;
private double dt = 0.03;
private Image buffer;
private Graphics gBuf;
public void run() {
double t = 0.0;
V = S.copy();
while (t < duration) {
V = Point.add(V, calcVelocity(V, S, E, t, duration).scale(dt));
t += dt;
repaint();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
public void paint(Graphics g) {
if (gBuf == null) {
buffer = createImage(WIDTH, HEIGHT);
gBuf = buffer.getGraphics();
}
gBuf.setColor(Color.WHITE);
gBuf.fillRect(0, 0, WIDTH, HEIGHT);
gBuf.setColor(Color.BLACK);
gBuf.fillOval((int)(V.x - 5), (int)(V.y - 5), 11, 11);
g.drawImage(buffer, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
public Point calcVelocity(Point current, Point start, Point goal, double t, double T) {
double L = Point.distance(start, goal);
double a = -6.0 / (T * T * T);
double b = 3.0 / (2.0 * T);
double s = (t - 0.5 * T);
double v = a * s * s + b;
return Point.subtract(goal, start).scale(v);
}
}
class Point {
public double x;
public double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public Point copy() {
return new Point(x, y);
}
public static double distance(Point p, Point q) {
double dx = p.x - q.x;
double dy = p.y - q.y;
return Math.sqrt(dx * dx + dy * dy);
}
public static Point add(Point p, Point q) {
return new Point(p.x + q.x, p.y + q.y);
}
public static Point subtract(Point p, Point q) {
return new Point(p.x - q.x, p.y - q.y);
}
public Point scale(double s) {
return new Point(x * s, y * s);
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
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.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I wrote a program that makes rectangles move. But so far they move only up and down. Now I need to make them move in circles(endless). Here is what I have already done:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
class GrimMain {
static JFrame frame = new JFrame();
//final static List<Rect> rectangles = new ArrayList<Rect>();
//final static int count = 0;
public static void main(String[] args) {
DrawingComponent fps = new DrawingComponent();
int pos = 100;
Rect r1 = new Rect(pos+100, 100, 30, 30, Color.red);
Rect r2 = new Rect(pos+140, 100, 30, 30, Color.blue);
Rect r3 = new Rect(pos+180, 100, 30, 30, Color.green);
fps.addRect(r1);
fps.addRect(r2);
fps.addRect(r3);
fps.animate();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fps.setPreferredSize(new Dimension(800, 600));
frame.getContentPane().add(fps);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class Rect {
int x;
int y;
int height;
int width;
Color color;
Rect(int x, int y, int width, int height, Color color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
public void draw(Graphics g) {
g.setColor(color);
g.fillRect(x, y, width, height);
}
public int getY() {
return y;
}
public int getX() {
return x;
}
public int getHeight() {
return height;
}
public void setY(int y) {
this.y = y;
}
public void setX(int y) {
this.x = x;
}
}
class DrawingComponent extends JComponent {
private static final int ANIMATION_DELAY = 10;
private List<Rect> rectList = new ArrayList<Rect>();
private int deltaY = 2;
DrawingComponent() {
}
public void animate() {
// here is the part with animation
new Timer(ANIMATION_DELAY, new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
for (Rect rect : rectList) {
int y = rect.getY();
if (y + rect.getHeight() >= getHeight()) {
deltaY = -Math.abs(deltaY);
}
else if (y <= 0) {
deltaY = Math.abs(deltaY);
}
rect.setY(y + deltaY);
}
repaint();
}
}).start();
}
public void addRect(Rect rect) {
rectList.add(rect);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Rect rect : rectList) {
rect.draw(g);
}
}
}
In this code you are only changing the y coordinate.
for (Rect rect : rectList) {
int y = rect.getY();
if (y + rect.getHeight() >= getHeight()) {
deltaY = -Math.abs(deltaY);
}
else if (y <= 0) {
deltaY = Math.abs(deltaY);
}
rect.setY(y + deltaY);
}
You can similarly change the x coordinate as well according to the circle's equation.
For example if the centre of circle is (x0,y0) and radius is r, you can set the initial value of theta, make small changes in theta and update the new x and y coordinates of the rectangle.
x = x0 + r*cos(theta_initial + delta_theta)
y = y0 + r*sin(theta_initial + delta_theta)
This code is taken from TheChernoProject 3D Game Programming episode 5
int x = (int) (Math.sin(System.currentTimeMillis() % 2000.0 / 2000 * Math.PI * 2) * 200);
int y = (int) (Math.cos(System.currentTimeMillis() % 2000.0 / 2000 * Math.PI * 2) * 200);
All you need to do is place this inside your paintComponent or whatever you use to render your rectangles and then use the x & y values.
Basically my entire program is to have shapes move across a JFrame,
and the problem I am having is that I cannot get my object to move.
I have a class called Creatures and the constructor creates my body and tail of my fish.
(I'm making an aquarium). This class extends to another class that has a move() method, so that everytime a timer event happens the picture moves.
Again my problem is that I cannot get the picture/shape/object to move.
If anyone could lend a hand I would be most grateful =]
Here is the full class of Creatures
import java.awt.geom.Ellipse2D;
import java.awt.Color;
import java.awt.Polygon;
import java.awt.Graphics2D;
public class Creatures extends Moveable2DShape{
private Color color;
private int delay, number;
private int xPos2, yPos2;
private final int POINTS = 3;
private int []x = new int[POINTS];
private int []y = new int[POINTS];
private double width, height;
Ellipse2D.Double body;
Polygon tail;
public Creatures(int xPos, int yPos, int shapeWidth, int shapeHeight, int bwidth, int bheight, double xSpeed, double ySpeed, Color c){
super(xPos, yPos, shapeWidth, shapeHeight, bwidth, bheight, xSpeed, ySpeed);
color = c;
xPos2 = xPos;
yPos2 = yPos;
width = shapeWidth;
height = shapeHeight;
}
public Polygon triangle(int xPos, int yPos){
x[0] = xPos + 100;
x[1] = x[0];
x[2] = (int)(xPos + width/2);
y[0] = (int)(yPos + (height));
y[1] = yPos;
y[2] = (int)(yPos + height/2);
tail = new Polygon(x,y,POINTS);
return tail;
}
//public void move(){
}
public void draw(Graphics2D g){
body = new Ellipse2D.Double(xPos2, yPos2, width, height);
//System.out.println(xPos2 + " " + yPos2 + " " + width + " " + height);
triangle(xPos2, yPos2);
g.setColor(color);
g.fill(body);
g.fill(tail);
}
}
I'm supposed to override the move() method that is inherited from the Moveabled2DShape class but i havent yet because I just wanted to test out the method before overriding it. But now my problem is that I need to update xPos2 and yPos2
MY FULL SOLUTION OF THE CREATURES CLASS
import java.awt.geom.Ellipse2D;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.Polygon;
import java.awt.Graphics2D;
public class Creatures extends Moveable2DShape{
private Color color;
private int delay, number, t;
private int xPos, yPos;
private double xSpeed, ySpeed;
private final int POINTS = 3;
private int []x = new int[POINTS];
private int []y = new int[POINTS];
private double width, height;
private boolean dead;
Ellipse2D.Double body;
Polygon tail;
public Creatures(int xPos, int yPos, int shapeWidth, int shapeHeight, int bwidth, int bheight, double xSpeed, double ySpeed, Color c, int type, boolean l){
super(xPos, yPos, shapeWidth, shapeHeight, bwidth, bheight, xSpeed, ySpeed);
color = c;
this.xPos = xPos;
this.yPos = yPos;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
width = shapeWidth;
height = shapeHeight;
t = type;
dead = l;
}
/*#x[3] calculate the x position points of the tail
*#y[3] calculate the y position points of the tail
*#tail create the polygon using the points and a defined constant of 3
*#return the polygon #tail*/
public Polygon triangle(int xP, int yP){
x[0] = xP + 100;
x[1] = x[0];
x[2] = (int)(xP + width/2);
y[0] = (int)(yP + (height));
y[1] = yP;
y[2] = (int)(yP + height/2);
tail = new Polygon(x,y,POINTS);
return tail;
}
/*#newBW will determine the new width of the bounding box
*#return the new bounding box width*/
public int newBWidth(){
int newBW;
newBW = (int)(x[0] - getBoundingBoxMaxX()) + (int)getBoundingBoxWidth();
return newBW;
}
/*when called, the move method of Creatures will move along the x-values\
*set the new bounding box with the new calculated width */
public void move(){
this.xPos=(int) (getXPos() - xSpeed);
int overShoot = (int) (xPos + getBoundingBoxWidth() - environmentWidth);
if (xPos <= 0)
{
xPos = 0;
xSpeed = -xSpeed ;
}
else if (overShoot > 0)
{
xPos = (int)(environmentWidth - getBoundingBoxWidth());
xSpeed = - xSpeed ;
}
/*
Reflect the object if it goes too far
*/
overShoot = (int) (yPos + getBoundingBoxHeight() - environmentHeight);
if (yPos <= 0)
{
yPos = 0;
ySpeed = -ySpeed ;
}
else if (overShoot > 0)
{
yPos = (int) (environmentHeight - getBoundingBoxHeight());
ySpeed = - ySpeed ;
}
if(xPos == 0 || xPos == 880){
this.yPos =+ (int)(getYPos() + ySpeed);
}
if(yPos == 650){
this.yPos =+ (int)(getYPos() + ySpeed);
}
// move the shape to the new position
moveTo(xPos,yPos);
setBoundingBox(getXPos() , getYPos() , newBWidth(), height);
}
/*Detect if two bounding boxes intersects with one another if two intersects
*call the collision response method and #return true, else #return false. */
public boolean collisionDetect(Moveable2DShape other){
if(getBoundingBox().intersects(other.getBoundingBox())){
return true;
}
return false;
}
/*#other2 cast the Moveable2DShape object into a Creatures object and compare
*if #other2 object type is greater than the current object then the current object dies
*if the two objects are equal to each other then change the color of both objects randomly
*otherwise #other2 dies. */
public void collisionResponse(Moveable2DShape other){
int []c2 = new int[3];
int []c3 = new int[3];
Creatures other2 = (Creatures) other;
if (getType() < other2.getType()){
fishiesDie();
}else if(getType() == other2.getType()){
for(int a = 0; a < 3; a++){
c2[a] = (int)(Math.random()*255) + 1;
c3[a] = (int)(Math.random()*255) + 1;
}
color = new Color(c2[0], c2[1], c2[2]);
other2.color = new Color(c3[0], c3[1], c3[2]);
}else{
other2.fishiesDie();
}
}
/*#return the type of the fish */
public int getType(){
return t;
}
/*#dead equals to true when called */
public void fishiesDie(){
dead = true;
}
/*#return dead */
public boolean isDead(){
return dead;
}
/*#body draw the general body ellipse
*#g set the colour and draw the general fish shape(body and tail)*/
public void draw(Graphics2D g){
body = new Ellipse2D.Double((int)getXPos(), (int)getYPos() , width, height);
triangle((int)getXPos(), (int)getYPos());
//g.draw(getBoundingBox());
g.setColor(color);
g.fill(body);
g.fill(tail);
}
}