i'm new in Java and working on a small project and having an issue, I hope you can help :
I'm trying to create a 2 dimensional array, inwhich each element is an Object of type Field that holds x and y ( as the coordinate of the element )
I'm throwing an error when the sent parameters for length and width are < 0
I'm testing my code in the main method but the error is always thrown meaning that the method to create the "map" is not receiving the correct parameters.
Note : the main method is in a different class ( main class )
```
import bbb.MyException;
public class CoordinateSystem {
private int length;
private int width;
private Field[][] map = createMap(getWidth(), getLength());
public CoordinateSystem(int width, int length) throws MyException {
this.width = width;
this.length = length;
}
public int getLength() {
return this.length;
}
public int getWidth() {
return this.width;
}
public class Field{
private int x;
private int y;
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
}
public Field[][] getMap() {
return map;
}
// Initializing a coordinate to each "field"
public Field[][] createMap(int width, int length) throws MyException {
if(width > 0 && length > 0){
Field[][] map = new Field[width][length];
for( int i = 0 ; i < width ; i++ ){
for( int j = 0 ; j < length ; j++ ){
map[i][j].setX(j);
map[i][j].setY(i);
}
}
return map;
} else{
throw new MyException("Sorry, can't create a field of width or height = 0 ");
}
}
}
public static void main(String[] args) throws MyException {
CoordinateSystem board = new CoordinateSystem(8, 9);
for( int i = 0 ; i < 8 ; i++ ){
for( int j = 0 ; j < 9 ; j++ ){
System.out.print(board.getMap()[i][j].getX());
System.out.println(board.getMap()[i][j].getY());
}
}
Exception in thread "main" bbb.MyException: Error! Sorry, can't create a
field of width or height = 0
at CoordinateSystem.createMap(CoordinateSystem.java:62)
at CoordinateSystem.<init>(CoordinateSystem.java:9)
at Main.main(Main.java:21)
Process finished with exit code 1
This line of your code (in method createMap())...
Field[][] map = new Field[width][length];
creates a two dimensional array but every element in the array is null.
Hence this line of your code (also in method createMap())
map[i][j].setX(j);
will throw a NullPointerException.
You need to explicitly create Field objects.
Also the Y coordinate of some of the Field elements in the map is zero as well as the X coordinate in some of the elements because (also in method createMap()) you start the for loops with zero. In order to fix that I add one to i and j when I call setX() and setY().
Here is the corrected code for the for loops in method createMap()
for( int i = 0 ; i < width ; i++ ){
for( int j = 0 ; j < length ; j++ ){
map[i][j] = new Field();
map[i][j].setX(j + 1);
map[i][j].setY(i + 1);
}
}
The only thing left to do is call method createMap(). Since map is a member of class CoordinateSystem, it seems logical to call createMap() from the constructor of CoordinateSystem.
public CoordinateSystem(int width, int length) throws MyException {
this.width = width;
this.length = length;
map = createMap(width, length);
}
Finally, for the sake of completeness, here is the entire [corrected] code of class CoordinateSystem
public class CoordinateSystem {
private int length;
private int width;
private Field[][] map;
public CoordinateSystem(int width, int length) throws MyException {
this.width = width;
this.length = length;
map = createMap(width, length);
}
public int getLength() {
return this.length;
}
public int getWidth() {
return this.width;
}
public class Field {
private int x;
private int y;
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
}
public Field[][] getMap() {
return map;
}
// Initializing a coordinate to each "field"
public Field[][] createMap(int width, int length) throws MyException {
if(width > 0 && length > 0){
Field[][] map = new Field[width][length];
for( int i = 0 ; i < width ; i++ ){
for( int j = 0 ; j < length ; j++ ){
map[i][j] = new Field();
map[i][j].setX(j + 1);
map[i][j].setY(i + 1);
}
}
return map;
}
else{
throw new Exception("Sorry, can't create a field of width or height = 0 ");
}
}
public static void main(String[] args) throws MyException {
CoordinateSystem board = new CoordinateSystem(8, 9);
for( int i = 0 ; i < 8 ; i++ ) {
for( int j = 0 ; j < 9 ; j++ ) {
System.out.print(board.getMap()[i][j].getX());
System.out.println(board.getMap()[i][j].getY());
}
}
}
}
You're initializing map before initializing width and height, so getWidth() and getHeight() both return 0. You can move the initialization inside the constructor and use the width and height there:
public class CoordinateSystem {
private int length;
private int width;
private Field[][] map;
public CoordinateSystem(int width, int length) throws MyException {
this.width = width;
this.length = length;
map = createMap(width, height);
}
// rest of the class...
Related
I am trying to use a generic method to sort an array. I am receiving an error on Lab6Sort(octArr); that says classname cannot be applied to Shape[].
public static void main(String[] args) {
Shape[] octArr = new Shape[10];
for(int i = 0; i < 10; i++){
octArr[i] = new L6MPerRegOct(Math.floor(Math.random() * 1000) / 10);
}
Lab6Sort(octArr);
}
.
.
public static <AnyType> void Lab6Sort (AnyType [] arr, Comparator<? super AnyType> cmp)
It seems that I need a second argument, but I am unsure what this should be.
Here is the complete code:
public class L6MPerRegOct extends Shape {
public static void main(String[] args) {
Shape[] octArr = new Shape[10];
for(int i = 0; i < 10; i++){
octArr[i] = new L6MPerRegOct(Math.floor(Math.random() * 1000) / 10);
}
Lab6Sort(octArr);
}
private double sideLength;
public L6MPerRegOct(double len){
sideLength = len;
}
public double area(){
return 2 * sideLength*sideLength * (1 + Math.sqrt(2));
}
public static <AnyType> void Lab6Sort (AnyType [] arr, Comparator<? super AnyType> cmp)
{
int j, minIndex, n = arr.length;
AnyType temp;
for ( int index = 0; index < n - 1; index++ ) {
minIndex = index;
for (j = index + 1; j < n; j++) {
if (cmp.compare(arr[index], arr[minIndex]) < 0)
minIndex = j;
}
if (minIndex != index) {
temp = arr[index];
arr[index] = arr[minIndex];
arr[minIndex] = temp;
}
}
public abstract class Shape implements Comparable<Shape>
{
public abstract double area( );
public abstract double perimeter( );
public int compareTo( Shape rhs )
{
double diff = area( ) - rhs.area( );
if( diff == 0 )
return 0;
else if( diff < 0 )
return -1;
else
return 1;
}
public double semiperimeter( )
{
return perimeter( ) / 2;
}
}
You need to pass it an instance of a Comparator, e.g.
Lab6Sort(octArr, new Comparator<Shape>() {
#Override
public int compare(Shape o1, Shape o2) {
return 0;
}
});
Or define the Comparator in a separate class, if you want to reuse it
public class ShapeComparator implements Comparator<Shape> {
#Override
public int compare(Shape o1, Shape o2) {
return 0;
}
}
class ShapeComparator implements Comparator<Shape> {
#Override
public int compare(Shape o1, Shape o2) {
return 0;
}
}
I was attempting to implement Fruchterman and Reingold algorithm in Java, but for some reasons, the coordinate of output vertices sometimes occupy the same coordinates, which is not something this algorithm would want. Where did I go wrong?
Coordinate object (vector)
public class Coordinates {
private float x;
private float y;
public Coordinates(float xx, float yy){
x = xx; y = yy;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public String toString(){
return x+" "+y;
}
public Coordinates subtract(Coordinates c){
return new Coordinates(x-c.x, y - c.y);
}
public Coordinates add(Coordinates c){
return new Coordinates(x + c.x, y + c.y);
}
public Coordinates unit(){
if(length() == 0)
return new Coordinates(0.000001f,0.0000001f);
else
return new Coordinates(x/(float)Math.sqrt(x*x + y*y),y/(float)Math.sqrt(y*y + x*x));
}
public float length(){
return (float)Math.sqrt(x*x + y*y);
}
public float distance(Coordinates c){
return (float) Math.sqrt((x-c.x)*(x-c.x) + (y-c.y)*(y-c.y));
}
public Coordinates scale(float k){
return new Coordinates(k*x,k*y);
}
}
Node object
import java.util.LinkedList;
public class Node {
private LinkedList<Node> incidentList; //has 30 elements for 30 vertices. 1 if incident, 0 if not
private int color;
private Coordinates coord;
private Coordinates disp;
public Coordinates getDisp() {
return disp;
}
public void setDisp(float x, float y) {
disp.setX(x);
disp.setY(y);
}
public void setDisp(Coordinates d) {
disp = d;
}
private int id;
public Node(){
incidentList = new LinkedList<Node>();
color = 0;
coord = new Coordinates(0,0);
disp = new Coordinates(0,0);
id = -1;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public LinkedList<Node> getIncidentList() {
return incidentList;
}
public void addEdge(Node n) {
incidentList.add(n);
}
public void removeEdge(Node n){
incidentList.remove(n);
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public Coordinates getCoord() {
return coord;
}
public void setCoord(float x, float y) {
coord.setX(x);
coord.setY(y);
}
public int getDegree(){
return incidentList.size();
}
public boolean isAdjacent(Node n){
return incidentList.contains(n);
}
}
Graph object (with layout algorithm function frlayout)
import java.util.ArrayList;
import java.util.Random;
public class MyGraph{
private final int DISRESPECT = -1;
private final int MORECOLOR = -3;
private final float EPSILON = 0.003f;
private ArrayList<Node> graphNodes; //maximum of 30 vertices
private int nVertices = 0;
private int score = 50;
int maxColor = 0;
int[] colorPopulation = new int[15];
double boundx, boundy, C;
public double getBoundx() {
return boundx;
}
public void setBoundx(double boundx) {
this.boundx = boundx;
}
public double getBoundy() {
return boundy;
}
public void setBoundy(double boundy) {
this.boundy = boundy;
}
public double getC() {
return C;
}
public void setC(double c) {
C = c;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getnVertices() {
return nVertices;
}
public MyGraph(){
graphNodes = new ArrayList<Node>();
}
public ArrayList<Node> getGraphNodes() {
return graphNodes;
}
//add a new node into the graph
//also set the id of that node
public void addNode(Node n){
graphNodes.add(n);
n.setId(nVertices++);
}
public void addEdge(Node n1, Node n2){
n1.addEdge(n2);
n2.addEdge(n1);
}
//randomly generate a graph with parsity
public void randomGenerating(double parse){ //parse is between 0 and 1
Random gen = new Random(System.currentTimeMillis());
int tempNVertices = 6; //CHANGE HERE TO BECOME A RANDOM NUMBER
for(int i = 0; i< tempNVertices; i++){
Node n = new Node();
float x = 0,y = 0;
while(true){
boolean flag = true;
x = gen.nextFloat();
y = gen.nextFloat();
for(int j = 0; j < i; j++){
if(x*boundx == graphNodes.get(j).getCoord().getX() && y*boundx == graphNodes.get(j).getCoord().getY())
flag = false; break;
}
if (flag)
break;
}
n.setCoord((float)(x*boundx),(float)(y*boundy));
addNode(n);
}
for(int i = 0; i < tempNVertices; i++){
for(int j = i + 1; j < tempNVertices; j++){
if(gen.nextDouble() < parse){
addEdge(graphNodes.get(i),graphNodes.get(j));
}
}
}
}
public void frLayout(){
double w = boundx, h = boundy;
double area = w*h;
double k = C*Math.sqrt(area/nVertices);
double temperature = 1000;
for(int i = 0; i < nVertices; i++)
System.out.println(graphNodes.get(i).getCoord().getX()+" "+graphNodes.get(i).getCoord().getY());
System.out.println("------------------------------");
for(int m = 0; m< 900; m++){
for(int i = 0; i < nVertices; i++){
Node v = graphNodes.get(i);
v.setDisp(0,0);
for(int j = 0; j< nVertices; j++){
Node u = graphNodes.get(j);
if(i!= j){
Coordinates delta = v.getCoord().subtract(u.getCoord());
double myFr = fr(u,v,k);
v.setDisp(v.getDisp().add(delta.unit().scale((float)myFr)));
if(Double.isNaN(v.getDisp().getX())){
System.out.println("PANIC: "+u.getCoord().getX()+" "+u.getCoord().getY()+" "+delta.getX()+" "+v.getCoord().getX());
return;
}
}
}
}
for(int i = 0; i < nVertices; i++){
Node v = graphNodes.get(i);
for(int j = i+1; j< nVertices; j++){
Node u = graphNodes.get(j);
if(v.isAdjacent(u)){
Coordinates delta = v.getCoord().subtract(u.getCoord());
double myFa = fa(u,v,k);
v.setDisp(v.getDisp().subtract(delta.unit().scale((float)myFa)));
u.setDisp(u.getDisp().add(delta.unit().scale((float)myFa)));
}
}
}
for(int i = 0; i< nVertices; i++){
//actually adjusting the nodes
Node v = graphNodes.get(i);
if(i == 0){
System.out.println(v.getCoord().getX()+" "+v.getCoord().getY());
Coordinates disp = v.getDisp().unit().scale((float)Math.min(v.getDisp().length(), temperature));
System.out.println(">>"+disp.getX()+" "+disp.getY());
}
Coordinates newCoord = (v.getCoord().add(v.getDisp().unit().scale((float)Math.min(v.getDisp().length(), temperature))));
v.setCoord(newCoord.getX(), newCoord.getY());
// //prevent from going outside of bound
// float x = (float)Math.min(w, Math.max(0,v.getCoord().getX()));
// float y = (float)Math.min(h, Math.max(0, v.getCoord().getY()));
//
// v.setCoord(x,y);
if(i == 0){
System.out.println(v.getCoord().getX()+" "+v.getCoord().getY());
}
}
temperature *= 0.9;
System.out.println("TEMPERATURE = "+temperature);
}
for(int i = 0; i< nVertices; i++){
Node v = graphNodes.get(i);
System.out.println(v.getCoord().getX()+" "+v.getCoord().getY());;
}
}
private double fa(Node ni, Node nj, double k){
double distance = ni.getCoord().distance(nj.getCoord());
return distance*distance/k;
}
private double fr(Node ni, Node nj, double k){
double distance = ni.getCoord().distance(nj.getCoord());
return k*k/(distance+0.000001);
}
public static void main(String[] args){
MyGraph grph = new MyGraph();
grph.setBoundx(480);
grph.setBoundy(480);
grph.setC(1);
grph.randomGenerating(1);
grph.frLayout();
}
}
Apologies for the overly long question. I tried tutorials on net, but couldn't get anywhere closer to figuring out what's going wrong. Note that when finding unit vector, if a vector is zero (0,0), I make it a very small, non-zero vector so that when two vertices are close to one another, they will repel violently just as the author of the algorithm hoped.
Any instructions would be appreciated.
I found my bug. I was taking square root of the distance twice while computing the attraction and repulsion forces as well as a few other smaller bugs. I posted the corrected code in my question. Hopefully anyone out there attempting this algorithm will find it useful. Note that by removing the boundary, we let the graph free to evolve, it could produce better shape. Once obtaining the resulting graph, we could always translate/scale it so that it fit into whatever dimension required.
I am trying to implement image filter ( using convulution). I've spent all day trying to figure out what's going on and I cannot find a mistake. The filter works only when I use it to blur the image. In other cases it doesn't work properly: For example this is the original picture(before filtering):
And this is the picture after filtering with this matrix:
I use Marvin Image Processing Framework and jblas library in my code:
public class FiltrySploty extends MarvinAbstractImagePlugin {
#Override
public void load() {
}
#Override
public MarvinAttributesPanel getAttributesPanel() {
return null;
}
#Override
public void process(
MarvinImage imageIn,
MarvinImage imageOut,
MarvinAttributes attributesOut,
MarvinImageMask mask,
boolean previewMode) {
double norm=0;
DoubleMatrix filter = (DoubleMatrix)getAttribute("filter");
for ( int i = 0; i < filter.getRows();i++)
{
for ( int j = 0; j < filter.getColumns();j++)
{
norm=norm+filter.get(i, j);
}
}
int marginx = ((filter.getRows()-1)/2);
int marginy = ((filter.getColumns()-1)/2);
for (int x = marginx; x < imageIn.getWidth()-marginx; x++) {
for (int y = marginy; y < imageIn.getHeight()-marginy; y++) {
double SumRed=0;
double SumGreen=0;
double SumBlue=0;
for ( int i = x-marginx,k=0 ; k < filter.getRows();i++,k++)
{
for ( int j = y-marginy, l=0 ; l <filter.getColumns();j++,l++)
{
SumRed= SumRed+(filter.get(k, l)*imageIn.getIntComponent0(i, j));
SumGreen= SumGreen+(filter.get(k, l)*imageIn.getIntComponent1(i, j));
SumBlue= SumBlue+(filter.get(k, l)*imageIn.getIntComponent2(i, j));
}
}
SumRed = SumRed/norm;
SumGreen = SumGreen/norm;
SumBlue = SumBlue/norm; // normalization
if(SumRed>255.0) SumRed=255.0;
else if(SumRed<0.0) SumRed=0.0;
if(SumGreen>255.0) SumGreen=255.0;
else if(SumGreen<0.0) SumGreen=0.0;
if(SumBlue>255.0) SumBlue=255.0;
else if(SumBlue<0.0) SumBlue=0.0;
imageOut.setIntColor(x, y, (int)(SumRed), (int)(SumGreen), (int)(SumBlue));
}
}
}
}
Seeing the effect of filtering I suppose that the SumRed, SumGreen and SumBlue are out of range and they are setting to 255 or 0 values. But I have no idea why.
I want to find out whether a number passed through a method is part of a randomly generated object (created from a tree map). I've been looking online to find an attribute to the class that can help me find it but have come up short, I've tried HashCodes, Equals(), and this the like... At the moment I have it set up like this and what I'm asking, I guess, is whether I'm using what I read right or wrong?
Here's the code:
public class a {
private final TreeMap<Integer,TreeMap<Integer,Double>> rectangle;
private final int height;
private final int width;
public a(int h, int w) {
this.rectangle = new TreeMap<>();
this.height = h;
this.width = w;
}
public double get(int i, int j) {
if ( i > j ) {
largest = i; // defined earlier
}
for(int a = 0; a < largest; a++) {
if (this.height.equals(a) == i && this.width.equals(a) == j){
int[] position = new int[1];
position[0] = i;
position[1] = j;``
}
else {
return 0.0;
}
}
}
I have some problems with getting inheritance to work. In the parent class, the array Coefficients is private. I have some access methods but I still can't get it to work.
import java.util.ArrayList;
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;
}
}
Can anyone help me fix my Second class that inherits from the one above? I cant seem to get my multiply and add methods for the second class to work properly.
public class QuadPoly extends Poly
{
private float [] quadcoefficients;
public QuadPoly() {
super(2);
}
public QuadPoly(int degree) {
super(2);
}
public QuadPoly(float [] f) {
super(f);
if (getDegree() > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
}
public QuadPoly(Poly p){
super(p.coefficients);
for (int i = 0; i < coefficients.length; i++){
if (coefficients[i] < 0){
throw new Exception("Expecting positive coefficients!");
}
}
}
// public QuadPoly(Poly p){
// super(p.coefficients);
//}
public QuadPoly addQuad (QuadPoly p){
return new QuadPoly(super.add(p));
}
public QuadPoly multiplyQuadPoly (QuadPoly f){
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
return new QuadPoly(super.multiplyPoly(f));
}
I would make the coefficients protected or use an accessor method.
I wouldn't throw a plain checked Exception. An IllegalArgumentException would be a better choice.
What is quadcoefficients? They don't appear to be set anywhere.
You put coefficients private. I wouldn't change this but I would add a getter method into Poly class:
public class Poly {
//somecode here
public float[] getCoefficients(){
return this.coefficients;
}
}
Then I would use it by the getter method in other code;
public QuadPoly(Poly p){
super(p.getCoefficients);
//some more code here
}
Even if you make coefficient protected, you are trying to reach coefficients field of another Object, which is a parameter. So it is not related to inheritance and the problem.