I wanna get the different results as the inputted number.
For example, when I put 4 I get the results of the rectangle and when I put 3 I get the triangle.
import java.util.Scanner;
public class Source9_1 {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x, y; // 클래스 Parameter(내부 변수)
Point[] v = new Point[n]
for(int i=0; i <= v.length; i++) {
v[i] = new Point();
v[i].
}
}
class Point {
int x, y; // 클래스 Parameter (내부 변수)
public void setPoint(int x, int y) { // Point 세팅
this.x = x;
this.y = y;
}
public void printPoint() { // Point 출력
System.out.println("x = " + x + ", y = " + y);
}
}
class Rectangle extends Point {
Point[] p = new Point[4];
Rectangle(Point[] p) {
this.p = p;
}
}
class Triangle extends Point {
Point[] p = new Point[3]; // 3개의 Point인스턴스를 담을 배열 생성
Triangle(Point[] p) {
this.p = p;
}
}
class Shape extends Point { // Point 배열 및 상속을 받아 세팅 후 출력가능한 클래스
Point coord[10];
static int s = 0; // 불릴 때마다 값 증가 ???
public void printShapePoint() { // 배열에 담은 Point 출력
}
public void setShapePoint() { // 배열에 담기 위해 Point 증가
}
}
So far, I coded like this but I don't know what to do now.
How can I get the different result as I put the number?
This is the result what I want
First of all, about your Rectangle and Triangle classes. I feel like you have missed your point there (pun not intended), because you've put both extending the Point class. That doesn't make much sense, since you have the Shape class, which would do a much better job as the superclass for them.
So:
class Rectangle extends Shape {
...
}
class Triangle extends Shape {
...
}
With that out of the way, what you have so far:
You are capturing the number of points from the input;
You are creating an array of that size;
You are instantiating and setting an Point object for each of the array positions.
What you need to do next:
Capture the points coordinates from the input
Set said coordinates to the Point objects
Instantiate an Triangle or Rectangle object, depending on how many points you have.
So, inside your for statement you will want to do:
for (int i=0; i <= v.length; i++) {
v[i] = new Point();
x = sc.nextInt(); // Save 'x' value into the variable
y = sc.nextInt(); // Save 'y' value into the variable
v[i].setPoint(x, y); // Set both values using the method from Point
}
Then, since both Rectangle and Triangle have Shape as a common superclass, you are allowed to put objects of either one of these class in a Shape variable. So right after the for statement you will want to do:
Shape s; // Create the empty variable here, so it will exist outside the if-else scope
if (n == 3)
s = new Triangle(v);
else
s = new Rectangle(v);
Finally, just print your points:
for (int i = 0; i < v.length; i++)
v[i].printPoint();
And that's pretty much it.
The answer from Pedro is great. I have an additional suggestion to make. Using a switch or conditional to create the different types of shapes is a bit of a code smell. I suggest using an abstract factory for this. I put up a little example of how you could do this here.
Deducing the shape from the number of points might be insufficient. For instance, a rectangle is defined by two points (not four) and so would a line, even though you are not currently modeling lines.
I think it would be more clear to select the shape by name and use a factory to instantiate it from the entered points.
Note that he shapes object hierarchy is used a lot to explain object orientation. There are several pitfalls with designing class structures like this. See for example this article. Keep in mind also the Liskov Substitution principle which is easily violated, see this article.
Related
I'm working on a 2x2 rubik cube, and was having trouble getting one side rotate with my program. The cube is a 2d array of squares. I'm just triying to do a 90 degree counter clockwise turn.
This is what happens
https://imgur.com/a/tlskNKY
I changed the colour so I could see the specific squares and how they changed. I tried changing the order, moving specific pieces at a time to see if the problem was just overlapping pieces (no such luck).
//square class
public class square implements Comparable {
int c;
private Rectangle r;
int xpos, ypos, width, height;
public square(int a, int x, int y) {
c = a;
xpos = x;
ypos = y;
r = new Rectangle(xpos, ypos, 50, 50);
}
//some unused methods
}
//inside the cube class
public class cube{
square[] temp = new square[4]
square[][] sq= new square[6][4]
//two for loops make squares and fills the sq 2d array
//the result is in the imgur link
public void turnVc(){
temp= sq[2];
sq[2][0]=temp[1];
sq[2][1]=temp[3];
sq[2][2]=temp[2];
sq[2][3]=temp[0];
}
}
I expect the output to be the original image turned counter clockwise.
tmp is a pointer that points to the same object that sq[2] pointers. That's why when you change sq[2] content, you change tmp's as well.
i think instead of assign "temp= sq[2];" you should do the following:
temp = new square[4];
for (int i = 0; i < 4; i++) {
temp[i] = sq[2][i];
}
Edit:
i think a little improvement you could do is that you don;t need to save all the sq[2] array, you could only save the fist item. i would do like this (tmp is now a square, not an array):
tmp = sq[2][0];
sq[2][0] = sq[2][1];
sq[2][1] = sq[2][3];
sq[2][3] = sq[2][2];
sq[2][2] = tmp;
If your square class implements Cloneable, you should use clone() method possible, it is also similar to answer of #Nguyen Tan Bao, but shorter
I guess you 're C++ dev, reference in Java is like pointer in C++, you can research more Have fun !
So I am doing a project for my JAVA class finals. During the assignment, there is a question ask me to randomly assign one of four images (the flower images I have) to the image field in my Flower constructor. But I did not seem to understand this requirement. Can somebody help me with this? I will greatly appreciate. Here is my code. Also, my teacher has given us a hint that we should use an "if" statement for this.
import java.awt.Point;
import javax.swing.ImageIcon;
public class Flower {
private ImageIcon image;
private Point pos;
public Flower(int x, int y) {
pos = new Point(x,y);
}
}
Generating a random number from 0 to 4 will do the trick for you.
Suppose the 4 images you have is in the form of array of type ImageIcon.
If the name of the array is list_flowers.
your constructor can be-
public Flower(int x, int y) {
Random rand = new Random();
pos = new Point(x,y);
image = list_flowers[rand.nextInt(4)];
}
First things first, you need to change Flower so you can pass it the image to be used.
public class Flower {
private ImageIcon image;
private Point pos;
public Flower(ImageIcon image, int x, int y) {
pos = new Point(x,y);
}
}
Personal thing, but I prefer it this way, as the result of initialising the class can be reasoned about.
One solution would be to make use of the available functionality in the Java API. Because I'm lazy, this would mean making use of Collections.shuffle to "randomise" a list of objects.
It might go something like....
List<ImageIcon> images = new ArrayList<>(4);
images.add(new ImageIcon(...)); // Flower 1
images.add(new ImageIcon(...)); // Flower 2
images.add(new ImageIcon(...)); // Flower 3
images.add(new ImageIcon(...)); // Flower 4
for (int index = 0; index < numberOfFlowersToCreate; index++) {
int xPos = ...; // Calculate x position
int yPos = ...; // Calculate y position
Collections.shuffle(images);
ImageIcon image = images.get(0);
Flower flower = new Flower(image, xPos, yPos);
// Do something with the instance of Flower
}
So I to create a method that checks if the point " ponto " is inside the triangle given by the points A,B,C as vertices.
So far I have this :
final double PRECISION = 0.1;
public boolean dentroDoTriangulo (Point A, Point B, Point C, Point ponto){
//total
double ABC = Math.abs ((A.x*(B.y-C.y)+B.x*(C.y-A.y)+ C.x*(A.y-B.y))/2);
//parcial
double ABP = Math.abs((A.x*(B.y-ponto.y)+B.x*(ponto.y-A.y)+ponto.x*(A.y-B.y))/2);
double APC = Math.abs (A.x*(ponto.y-C.y)+ponto.x*(C.y-A.y)+C.x*(A.y-ponto.y))/2;
double PBC = Math.abs (ponto.x*(B.y-C.y)+B.x*(C.y-ponto.y)+C.x*(ponto.y-B.y))/2;
double parciais = ABP + APC + PBC ;
return Math.abs(ABC - parciais) <= PRECISION;
}
I've already tried doing it like :
ABP +APC +PBC == ABC
Nothing either, can someone help me understand what am I doing wrong here ?
EDIT: Your code seems to work OK. Here's a Point class example in case that's where you are crashing.
public class Point {
float x;
float y;
Point() {
x = 0;
y = 0;
}
Point(float x, float y) {
this.x = x;
this.y = y;
}
}
Just in case, I propose another solution:
Check out this algorithm for determining if the point is inside a triangle.
I cannot see your Point class so I do not know if there is a bug there. I assume it is two floats for x&y coordinates. We'll assume it's ok.
Can you explain your algorithm a bit better? I looks like you are taking three areas of the sub-triangles and adding them up to compare against the original triangle (with PRECISION tolerance). Try the "SameSide" function three times as mentioned in hyperlink if you want--which takes two cross products and then the dot product of the results of the cross products to determine if a point is on the "correct side" of a line between any two of the vertices (there are three such lines).
Code snippet for algorithm:
boolean SameSide(p1, p2, a, b) {
int[] cp1 = CrossProduct(b - a, p1 - a);
int[] cp2 = CrossProduct(b - a, p2 - a);
if (DotProduct(cp1, cp2) >= 0) {
return true;
}
return false;
}
boolean PointInTriangle(p, a, b, c) {
if (SameSide(p, a, b, c) && SameSide(p, b, a, c) &&
SameSide(p, c, a, b) {
return true;
}
return false;
}
Where a, b, c are the vertices and p is the point. I recommend int [] to hold the vectors. You will need to write the helper functions to calculate vector manipulations.
I could not follow your algorithm, but you could send out horizontal (or any direction for that matter) rays in two directions from the point. If it hits the triangle in both directions, then the point will be inside the triangle. You will need to be careful of special conditions where the ray hits a vertex. That would be considered as hitting two lines on one side. But as long as the ray hits the triangle in both directions, the point will be inside.
So I used your code for method dentroDoTriangulo and stuck is inside a class. I used the Point class given above. Then I called your method using the quick and dirty code given below. It seems to work without any problems. Like #TNT says above, a test case would be helpful.
public class Caller {
public static void main(String[] args) {
Triangle myTraingle = new Triangle();
boolean isInside = myTraingle.dentroDoTriangulo(new Point(1,0), new Point(3,0), new Point(2,2), new Point(2,1));
if (isInside) {
System.out.println("Point is inside");
} else {
System.out.println("Point is outside");
}
}
}
This is my Lab class which contains a method called findNearest() which takes a single Point object as a parameter and an ArrayList of Points as a parameter and returns the nearest Point in the list to the single Point.
In my main method I created an ArrayList of 10 random Point objects. drawn on Points on the StdDraw canvas.
I want to connect the points closest to another point in the ArrayList but I don't know how...can anyone help me out?
import java.util.ArrayList;
public class Lab {
public static void main(String[] args){
//Create 10 random points and put them in a List
ArrayList<Point> thePoints = new ArrayList<Point>();
for(int i=0; i<10; i++){
Point p = new Point(600 * Math.random(), 600 * Math.random());
thePoints.add(p);
}
StdDraw.setCanvasSize(600,600);
StdDraw.setXscale(0.0 , 600.0);
StdDraw.setYscale(0.0 , 600.0);
//Draw the points in the List
for( Point p : thePoints){
p.draw();
}
//Draw lines to the nearestNeighbors
StdDraw.show();
}
public static Point findNearest(Point aPoint, ArrayList<Point> theList){
double minimumDistSoFar = Double.MAX_VALUE;
Point nearest = null;
for (Point p : theList) {
if (p.getMyX() == minimumDistSoFar && p.getMyY() == minimumDistSoFar) {
}
double pDistance = distance(p);
if (pDistance < minimumDistSoFar) {
minimumDistSoFar = pDistance;
nearest = p;
}
}
return nearest;
}
}
StdDraw has a line() method. Here's a link to the documentation: Documentation
This method takes four doubles, x and y of the start of the line, and x and y of the end of the line. You could draw a line beginning at one of the Point's x and y, and then set the x and y of the end of the line to the nearest Point's x and y.
I imagine you could do something like this:
for(Point p : thePoints)
{
Point p2 = findNearest(p, thePoints);
StdDraw.line(p.getX(), p.getY(), p2.getX(), p2.getY());
}
From my understanding this should draw a line from the point in the loop to the nearest point.
I know this has been asked a lot but I'd like to know how to rotate a Tetris piece?
I already made a long and bad solution (~170 lines of code) but there should be easier way to do it.
My tetris pieces consist of 4 blocks which all know their location (row and column) in the matrix. Matrix itself is char-typed, so 4 blocks are all letters. It looks like this for example:
......
..T...
.TTT..
......
I tried to simulate my matrix as coordinate system by counting the middle row and column and using it as an origo and then tried to apply this simple algorithm I found:
90 degree rotation (x,y) = (-y,x)
It appears that it works only if my piece is in the center of matrix. I have no idea what I should do, I've been thinking this all day. Here's my method:
public void rotatePiece(ArrayList<Block> random) {
int distance = 0; // how far is the origo
for (int i=0; i < 4; ++i)
board[random.get(i).getRow()][random.get(i).getColumn()] = '.'; // erases the current location of the piece
for (int i=0; i < 4; ++i) {
distance = Math.abs(random.get(i).getColumn()-middleColumn);
if (random.get(i).getColumn() < middleColumn)
random.get(i).setColumn(random.get(i).getColumn()+(distance*2)); // "throws" the location of the block to the other side of the origo
else
random.get(i).setColumn(random.get(i).getColumn()-(distance*2));
int help = random.get(i).getColumn();
random.get(i).setColumn(random.get(i).getRow()); // (x, y) = (-y, x)
random.get(i).setRow(help);
}
for (int i=0; i < 4; ++i)
board[random.get(i).getRow()][random.get(i).getColumn()] = random.get(0).getStyle(); // saves the new location of the piece in the matrix
I would recommend defining four states for each block-group.
enum ROTATION {
UP, DOWN, LEFT, RIGHT;
ROTATION rotateLeft() {
switch(this) {
case UP: return LEFT;
case LEFT: return DOWN;
case DOWN: return RIGHT;
case RIGHT: return UP;
}
return null; // wont happen;
}
ROTATION rotateRight() {
ROTATION r = this;
// wow I'm lazy, but I've actually seen this in production code!
return r.rotateLeft().rotateLeft().rotateLeft();
}
}
abstract class Brick {
Point centerPos;
ROTATION rot;
abstract List<Point> pointsOccupied();
}
class TBrick extends Brick {
List<Point> pointsOccupied() {
int x = centerPos.x();
int y = centerPos.y();
List<Point> points = new LinkedList<Point>();
switch(rot) {
case UP: points.add(new Point(x-1,y);
points.add(new Point(x,y);
points.add(new Point(x+1,y);
points.add(new Point(x, y+1);
break;
case Down: points.add(new Point(x-1,y);
points.add(new Point(x,y);
points.add(new Point(x+1,y);
points.add(new Point(x, y-1);
break;
// finish the cases
}
}
}
You can use a rotation matrix.
You will need to set the origin of your rotation appropriately, which may mean translating the location of the piece with respect to the playing field (such that the origin is in the centre, for example), applying the rotation matrix and then translating it back to its correct location on the playing field coordinates.
The easiest and computational fastest way to do this, would to use precompute them.
That means a tetris piece will look like
class TetrisBlock {
String position[4];
int curPos = 0;
void rotateLeft() {
curPos++;
if (curPos > 3)
curPos = 0;
}
....
}
And then you could define something like
class TetrisTBlock extends TetrisBlock {
...
// in constructor
position={"....\n.T..\nTTT.\n....",
".T..\nTT..\n.T..\n.....",
// I guess you get the idea
...
You do this for every type of block and then you can also add members for adding/removing them from the board.
If you optimize you would go away from the chars....
I think the best way is to hard-code it. Take into consideration that each figure is different and each of the figure's rotation phase is also different. And for each rotation phase - determine which parts of the grid you need to be free (avoid collision).
For a visual representation check this