I'm trying to create two classes, one to define a point and another for array operations. I'm trying to create a method to sort an array of coordinates in ascending order based on y coordinates. I've tried following examples, but I keep running into a runtime error where the array is only partially sorted.
public class Point
{
private double x;
private double y;
public Point(double x_coord, double y_coord)
{
x = x_coord;
y = y_coord;
}
public boolean lessThan(Point anotherPoint)
{
if(y < anotherPoint.y)
{
if(x < anotherPoint.x)
{
return true;
}
}
return false;
}
}
public class PointArray
{
private Point[] points = new Point[count];
public PointArray(double[] doubleArray)
{
if(doubleArray.length % 2 == 0)
{
for(int i = 0, j = 0; i < 3; i++, j += 2)
{
double x = doubleArray[j];
double y = doubleArray[j + 1];
points[i] = new Point(x, y);
}
}
else
{
System.out.println("Error: The given array must be even.");
System.exit(0);
}
}
public void sort()
{
double x = 0;
double y = 0;
Point newPoint = new Point(x, y);
Point temp = new Point(x, y);
for (int i = 0; i < points.length - 1; i++)
{
for(int j = i + 1; j < points.length; j++)
{
int minIndex = i;
if(points[minIndex].lessThan(points[j]) == false)
{
temp = points[minIndex];
points[minIndex] = points[j];
points[j] = temp;
}
}
}
}
This code causes the array {5.6, 7.1, 4.9, 13.17, 9.3, 2.9} to first be stored as ordered pairs {(5.6, 7.1), (4.9, 13.17), (9.3, 2.9)}. but it does not sort them properly. After the first and third points are swapped, the second and third are not, even though the y coordinate of the third is smaller.
[(9.3, 2.9), (4.9, 13.17), (5.6, 7.1)]
EDIT: Another issue appeared related to the same assignment. This method is supposed to take two PointArray objects and compare them for equality by the x and y components. My idea was to sort both arrays and then compare the components using a method in the Point class, but I'm not sure how to define each PointArray in terms of an (x, y) point.
public boolean equals(Point anotherPoint)
{
if(x == anotherPoint.x && y == anotherPoint.y)
{
return true;
}
return false;
}
public boolean equals(PointArray anotherPointArray)
{
double x = 0;
double y = 0;
double xAnother = 0;
double yAnother = 0;
Point newPoint = new Point(x, y);
Point newAnotherPoint = new Point(xAnother, yAnother);
anotherPointArray.sort();
for(int i = 0; i < points.length; i++)
{
for(int j = 0; i < points.length; j++)
{
if(newPoint.equals(newAnotherPoint))
{
return true;
}
}
}
return false;
}
Your current lessThan method will give true only if both x and y are smaller. To sort by y alone use
public boolean lessThan(Point anotherPoint)
{
return y < anotherPoint.y;
}
Related
I'm trying to fill a matrix with stars (*) to draw Bresenham's line, but when i'm printing out the thing the matrix is only filled with one star i don't know whats wrong. Language is Java
public class PtLine extends VectorObject{ // inherites from another class
private int bx;
private int by;
private int delX;
private int delY;
public PtLine(int id,int x,int y,int bx,int by){
super(id,x,y);
this.bx = bx;
this.by = by;
this.delX = this.bx-x;
this.delY = this.by-y;
}
public void draw ( char [][] matrix ){ // filling the martic with stars
int D = 2*delY - delX;
matrix[x][y] = '*';
int j = y;
for (int i=x+1;i==bx;i++){
if(D > 0){
j+=1;
matrix[i][j]='*';
D = D + (2*delY-2*delX);
}
else{
matrix[i][j]='*';
D = D + (2*delY);
}
}
}
}
The following code is when i'm trying to print out the matrix
class Question3{
public static void main ( String args [] ){
char[][] matrix = new char[20][20];
for (int y = 0; y < 20; y++) {
for (int x = 0; x < 20; x++) {
matrix[y][x] = ' ';
}
}
PtLine n = new PtLine(6,6,6,13,13);
n.draw(matrix);
for (int y = 0; y < 20; y++) {
for (int x = 0; x < 20; x++) {
System.out.print(matrix[x][y]);
}
System.out.println();
}
}
}
It's likely that you have to change i==bx with i!=bx:
public void draw ( char [][] matrix ){ // filling the martic with stars
int D = 2*delY - delX;
matrix[x][y] = '*';
int j = y;
for (int i=x+1;i!=bx;i++){ // here
...
}
}
The for loop continues while this condition is true. In your code loop finishes immediately at start, before the first iteration, because this condition is false.
In my program, I am attempting to find the closest point from the starting position (0,0), then "move" again to the next point. The points are read in through a file. The next point I am trying to move to is the "closest" point. I use the Pythagorean Theorem to find the distance. But what can I do to "check" the point I am going to to determine if I have already have visited it. For instance, if the point is 0,0, and then it goes to 1,1, how do check to "tell" the program that 0,0 is no longer an option?
public class PointsNStuff {
public static void main(String [] args) {
final int P = StdIn.readInt();
double [] x = new double[P];
double [] y = new double[P];
double [] visit= new double[P]; //Set an array that stores points that have been visited already
double [] math= new double[P]; //Set an array that stores the distance to all the points
for( int i= 0; i< P; i++){ //Store the values from the text file
x[i] = StdIn.readDouble();
y[i] = StdIn.readDouble();
}
double lowX = x[0];
double lowY = y[0];
double highX = x[0];
double highY = y[0];
//Find the lowest X and the lowest Y values:
for (int i = 0; i < P; i++){
if (lowX > x[i])
lowX = x[i];
}for (int i = 0; i < P; i++){
if (lowY > y[i])
lowY = y[i];
}
for (int i = 0; i < P; i++){
if (highX < x[i])
highX = x[i];
}
for (int i = 0; i < P; i++){
if (highY < y[i])
highY = y[i];
}
System.out.println(lowX + " " + lowY);
System.out.println(highX + " " + highY);
System.out.println("");
System.out.println(P);
//Determine the closest point
double xCoord=0.0;
double yCoord=0.0;
double dist = -1.0;
for (int i= 0; i < P; i ++){ //Repeat entire section for all P (number of points)
for (int j = 0; j < P; j++){ //Find the distance between current point and all other points. Go through all points (do the math).
xCoord = x[j]; // # x point
yCoord = y[j]; // # y point
double save= Math.sqrt( ( (xCoord+x[j]) * (xCoord+x[j]) ) + ( (yCoord + y[j]) * (yCoord + y[j]) ) ); //Pythagorean theorem
save = math[j]; //store the distance in the array slot
}
for (int j = 0; j < P; j++){
if (dist < math[j]){
dist = math[j];
//What boolean check can I put here to double check whether I have visited this point already?
xCoord = x[j]; // set the two points to what number they should be at.
yCoord = y[j];
}
}
System.out.println(xCoord + " " + yCoord);
}
}
}
I have not used any points into the Array I named "visit". Any and all help is appreciated! Thanks!
Use ArrayList to Store points,
ArrayList<Double> x = new ArrayList<Double>();
ArrayList<Double> y = new ArrayList<Double>();
add points to arraylist,
for( int i= 0; i< P; i++){ //Store the values from the text file
x.add(StdIn.readDouble());
y.add(StdIn.readDouble());
}
select point from araylist,
x.get(i); insted of x[i];
y.get(i); insted of y[i];
and remove already used points,
x.remove(new Double(used_x_value));
y.remove(new Double(used_y_value));
see Class ArrayList
What you have here is a perfect candidate for encapsulation! I would start by thinking about another object to encapsulate the 'point' concept you keep referring to:
class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}
One minor caveat: this assumes that you will not have duplicate x,y pairs in the input file. If you do, you may need to override hashcode and equals. But if not, this should do it. Then you can put these Points into a data structure ( see HashSet ) like this:
import java.util.Set;
import java.util.HashSet;
public class PointsNStuff {
public static void main(String args[]) {
Set<Point> pointsVisited = new HashSet<>();
//when you visit a point, put it in the set like this
//the numbers are just for example
Point currentPoint = new Point(10.0, 12.0);
pointsVisited.add(currentPoint);
//now in the future you can check if you 'visited' this point
if(!pointsVisited.contains(currentPoint)) {
System.out.println("Haven't been to current point yet...");
}
}
}
I'm working on a small exercise that involves making an interface of six die faces. The goal is to change the color of each die face when I hover over it. The issue I'm having is that I can only change the color of the first die face, not the proceeding. I've been reluctant to come here and ask because I feel my issue is so insignificant but I've been trying to get this to work for the last 4 days and I just can't figure it out. I feel there is something about iteration that I'm just quite not understanding yet.
Dice[] dice = new Dice[6];
void setup(){
size(600,100);
for(int i = 0; i < dice.length; i++){
dice[i] = new Dice(i*100,0,100,100);
}
imageMode(CORNER);
}
void draw(){
for(int i = 0; i < dice.length; i++){
for(int j = 0; j < dice.length; j++){
if(j!=i && dice[i].checkHover(mouseX,mouseY)){
dice[i].drawDice(i,true);
} else {
dice[i].drawDice(i,false);
}
}
}
}
class Dice{
PImage[] diceFace = new PImage[6];
PImage[] diceFaceHover = new PImage[6];
int x;
int y;
int w;
int h;
Dice(int bx, int by, int bw, int bh){
x = bx;
y = by;
w = bw;
h = bh;
for(int i = 0; i < dice.length; i++){//loads the images
diceFace[i] = loadImage(i+".png");
diceFaceHover[i] = loadImage(i+"h.png");
}
}
void drawDice(int i, boolean hover){
if(hover){
image(diceFaceHover[i],x,y,w,h);
} else {
image(diceFace[i],x,y,w,h);
}
}
boolean checkHover(float mx, float my){
if((mx > x && mx < w) && (my > y && my < h)){
return true;
} else {
return false;
}
}
}
I'll continue searching for a solution in the meantime.
You have bad condition for checking hover. Don't forget that w and h are same for all dices but you need position not size.
if( (mx > x & mx < x+w) && ( my >y && my < y+h ) )
package net.gfx;
public class TileSet {
public final int TILES = 627;
class Tiles {
int x = 0, y = 0;
int w = 0, h = 0;
}
public Tiles tiles[] = new Tiles[TILES];
public TileSet() {
for (int i = 0, y = 0; i < TILES; i++) {
for (int x = 0; x < 1280; x =+ 25) {
if (x > 1280) {
x = 0;
y += 40;
}
else {
tiles[i].x = x; //ERROR CAUSED HERE
tiles[i].y = y; //TO HERE *Unknown reason*
tiles[i].w = 40;
tiles[i].h = 40;
}
}
}
}
}
The Error im getting:
Exception in thread "main" java.lang.ExceptionInInitializerError
at net.jump.Jump.<clinit>(Jump.java:8)
Caused by: java.lang.NullPointerException
at net.gfx.TileSet.<init>(TileSet.java:24)
at net.gfx.Graphics.<clinit>(Graphics.java:10)
... 1 more
What I'm trying to do is basically create an array of tiles on a screen. Everyting else works besides the setting the Object array Values.
I've searched almost everywhere and haven't found anything. I bet its probaly some simple thing i missed.
You have to create an instance of Tiles before you can do any operation on it.
for (int i = 0, y = 0; i < TILES; i++) {
for (int x = 0; x < 1280; x =+ 25) {
if (x > 1280) {
x = 0;
y += 40;
}
else {
tiles[i] = new Tiles(); //instance created here.
tiles[i].x = x;
tiles[i].y = y;
tiles[i].w = 40;
tiles[i].h = 40;
}
}
}
You aren't initializing each Tiles in your array, as the default value is null.
Perhaps you should try initializing each Tiles:
for(int i = 0; i < tiles.length; i++){
tiles[i] = new Tiles();
}
After that, you could perform operations with each Tiles element in the array.
Could any help me start?
Using a class that I created before, I need to make a new class that specifically deals with QuadPoly. I think I have the constructors made correctly but i'm not a hundred percent sure.
public class Poly {
private float[] coefficients;
public static void main (String[] args){
float[] fa = {3, 2, 4};
Poly test = new Poly(fa);
}
public Poly() {
coefficients = new float[1];
coefficients[0] = 0;
}
public Poly(int degree) {
coefficients = new float[degree+1];
for (int i = 0; i <= degree; i++)
coefficients[i] = 0;
}
public Poly(float[] a) {
coefficients = new float[a.length];
for (int i = 0; i < a.length; i++)
coefficients[i] = a[i];
}
public int getDegree() {
return coefficients.length-1;
}
public float getCoefficient(int i) {
return coefficients[i];
}
public void setCoefficient(int i, float value) {
coefficients[i] = value;
}
public Poly add(Poly p) {
int n = getDegree();
int m = p.getDegree();
Poly result = new Poly(Poly.max(n, m));
int i;
for (i = 0; i <= Poly.min(n, m); i++)
result.setCoefficient(i, coefficients[i] + p.getCoefficient(i));
if (i <= n) {
//we have to copy the remaining coefficients from this object
for ( ; i <= n; i++)
result.setCoefficient(i, coefficients[i]);
} else {
// we have to copy the remaining coefficients from p
for ( ; i <= m; i++)
result.setCoefficient(i, p.getCoefficient(i));
}
return result;
}
public void displayPoly () {
for (int i=0; i < coefficients.length; i++)
System.out.print(" "+coefficients[i]);
System.out.println();
}
private static int max (int n, int m) {
if (n > m)
return n;
return m;
}
private static int min (int n, int m) {
if (n > m)
return m;
return n;
}
public Poly multiplyCon (double c){
int n = getDegree();
Poly results = new Poly(n);
for (int i =0; i <= n; i++){ // can work when multiplying only 1 coefficient
results.setCoefficient(i, (float)(coefficients[i] * c)); // errors ArrayIndexOutOfBounds for setCoefficient
}
return results;
}
public Poly multiplyPoly (Poly p){
int n = getDegree();
int m = p.getDegree();
Poly result = null;
for (int i = 0; i <= n; i++){
Poly tmpResult = p.multiByConstantWithDegree(coefficients[i], i); //Calls new method
if (result == null){
result = tmpResult;
} else {
result = result.add(tmpResult);
}
}
return result;
}
public void leadingZero() {
int degree = getDegree();
if ( degree == 0 ) return;
if ( coefficients[degree] != 0 ) return;
// find the last highest degree with non-zero cofficient
int highestDegree = degree;
for ( int i = degree; i <= 0; i--) {
if ( coefficients[i] == 0 ) {
highestDegree = i -1;
} else {
// if the value is non-zero
break;
}
}
float[] newCoefficients = new float[highestDegree + 1];
for ( int i=0; i<= highestDegree; i++ ) {
newCoefficients[i] = coefficients[i];
}
coefficients = newCoefficients;
}
public Poly differentiate(){
int n = getDegree();
Poly newResult = new Poly(n);
if (n>0){ //checking if it has a degree
for (int i = 1; i<= n; i++){
newResult.coefficients[i-1]= coefficients[i] * (i); // shift degree by 1 and multiplies
}
return newResult;
} else {
return new Poly(); //empty
}
}
public Poly multiByConstantWithDegree(double c, int degree){ //used specifically for multiply poly
int oldPolyDegree = this.getDegree();
int newPolyDegree = oldPolyDegree + degree;
Poly newResult = new Poly(newPolyDegree);
//set all coeff to zero
for (int i = 0; i<= newPolyDegree; i++){
newResult.coefficients[i] = 0;
}
//shift by n degree
for (int j = 0; j <= oldPolyDegree; j++){
newResult.coefficients[j+degree] = coefficients[j] * (float)c;
}
return newResult;
}
}
Out of this, I need to create a method that factors a Quadratic in two factors (if it has real roots), or in a constant ”1” polynomial factor and itself, if there are no real roots. The method should return an array of two QuadPoly objects, containing each factor.
public class QuadPoly extends Poly
{
private float [] quadcoefficients;
public QuadPoly() {
super(2);
}
public QuadPoly(float [] a) {
quadcoefficients = new float[a.length];
for (int i = 0; i <a.length; i ++){
quadcoefficients[i] = a[i];
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
}
}
public QuadPoly(Poly p){
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
}
public QuadPoly addQuad (QuadPoly p){
return new QuadPoly(super.add(p));
}
public Poly multiplyQuadPoly (Poly p){
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
Poly newResult = null;
new Result = multiplyPoly(p);
}
}
}
Edit:
Sorry. This is what I have going on for the factoring so far. The big problem with it is that I'm not too sure how to get the inheritance to work properly.
This is my New Factoring. It doesn't work. Can anyone give me some hints to get on the right path? I understand that I need to return Poly so i'm replacing the arrays there as you can tell by the first if statement but it won't let me progress as its says it requires (int, float). I've casted it but it still won't allow me. Thanks
public QuadPoly factor(){
double a = (double) getCoefficient(0);
double b = (double) getCoefficient(1);
double c = (double) getCoefficient(2);
QuadPoly newCoefficients = new QuadPoly(4);
double equa = Math.sqrt((b*b) - (4*a*c));
if (equa > 0){
newCoefficients.setCoefficient(0, (float) (-b + equa)/(2*a));
newCoefficients.setCoefficient(1, (float) (-b - equa)/(2*a));
}
if (equa ==0){
newCoefficients[0] = 1;
newCoefficients[1] = (-b + equa)/(2*a);
}
if (equa < 0){
newCoefficients[0] = 0;
newCoefficients[1] = 1;
}
return (QuadPoly) newCoefficients;
}
OK you have made a reasonable attempt. Inheritance is simple here, all you need is the constructors:
class QuadPoly extends Poly{
public QuadPoly(){ super(2); }
public QuadPoly(float[] f){
super(f);
if(coefficients.length!=2) throw new IllegalArgumentException("not quad");
}
}
and that's pretty much all! I hope you can see, that the same code as Poly is used for everything else, and the same field coefficients does all the same work as it did before.
Now, in the factorisation
you have dimmed your double[] newCoefficients as size 1. too small!
you have tried to square-root your discriminant without knowing that it is positive!
you are returning an array of 2 doubles as your answer. you need two Polys. You haven't provided a method return type for factor
I suggest you use
public QuadPoly[] factor(){
}
as the signature. The rest is just maths!
The idea of subclassing Poly into QuadPoly is so that you can reuse as many of the old Poly methods as possible. Now, all your old methods use the array float[] coefficients, and your new QuadPoly inherits this field.
Why have you created a new field quadcoefficients[] ? It suffices to check in any constructor that there are only 3 members in the array, but to still harness the existing field coefficients[].
If you do this, all your old methods will still work! Only, they will return generic Poly. Since the QuadPoly must conform to the contract of a Poly, this is probably OK. The method multiplyCon is the only one that could be guaranteed to return another QuadPoly anyway.
You don't seem to have attempted a factorisation yet. Do you have any ideas? Well, here's a clue: you'll need to use something like
if (DISCRIMINANT >= 0) {
} else{
}