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.
Related
I am making a grid with the amounts determined by a scanner. I keep getting an error and I am not sure why. Here is the code for the grid that I am trying to make, I will also include the object and class for the maze/grid below.
public static void mazeSetup() {
System.out.println("How many rows and columns do you want? I would\n"
+ "suggest 10 minimum and 20 maximum.");
boolean mazeselect = true;
while(mazeselect) {
maze.columns = sc.nextInt();
maze.rows = maze.columns;
if (maze.rows > 30 || maze.rows < 10) {
System.out.println("Make sure that you make it within 10-30 rows.");
} else {
mazeselect = false;
}
}
mazeBuild();
}
public static void mazeBuild() {
for(int x = 0; x < maze.rows; x++) {
for(int y = 0; y < maze.columns; y++) {
maze.maze[x][y]= ".";
System.out.print(maze.maze[x][y]);
}
System.out.println();
}
characterPlacement();
}
I also have the object here:
static Maze maze = new Maze(null,0,0,0,0);
and the class with construtors for the maze/grid.
public class Maze {
String maze[][];
int rows;
int columns;
int xStart;
int yStart;
public Maze(String xMaze[][], int xRows, int xColumns, int xxStart, int xyStart) {
maze = xMaze;
rows = xRows;
columns = xColumns;
xStart = xxStart;
yStart = xyStart;
}
public String[][] maze() {
return maze;
}
public int rows() {
return rows;
}
public int columns() {
return columns;
}
public int xStart() {
return xStart;
}
public int yStart() {
return yStart;
}
}
Any help would be greatly appreciated. Thanks a lot! :D
Note: No errors occur until ran in console.
your String maze[][] is null because of this:
static Maze maze = new Maze(null,0,0,0,0); // notice that null
And you're trying to put values in it upon calling mazeBuild(). You should initialize it or pass an array instead of null. You can do this at the start of mazeBuild()
public static void mazeBuild() {
maze.maze = new String[maze.rows][maze.columns]; // <-- this one!
for(int x = 0; x < maze.rows; x++) { // <-- this loop tries to
for(int y = 0; y < maze.columns; y++) { // put values in your
maze.maze[x][y]= "."; // maze.maze (2D String array)
System.out.print(maze.maze[x][y]);
}
System.out.println();
}
You can also do this in exchange to the line of code I've added.
String[][] mazeArray = new String[maze.rows][maze.columns];
maze = new Maze(mazeArray, maze.rows, maze.columns, 0, 0);
So I'm having the following problem: I have a method that breaks a big matrix into smaller blocks of the same size. After I do some operations on the blocks, I want to reconstruct the big matrix in the right order, but I'm going wrong at it somehow.
The following code reconstructs correctly a 4x4 matrix that breaks into 2x2, but for any other dimensions, it's not working properly.
public long[][] blocksToMatrix(List<long[][]> blocks, int blockDimension, int width, int height ){
long[][] yuvMatrix = new long[height][width];
int heightPos = 0;
int widthPos = 0;
for (int i = 0; i < blocks.size(); i++) {
long[][] yuvBlock = blocks.get(i);
int heightPosTemp = heightPos;
for (int j = 0; j < blockDimension * blockDimension; j++) {
yuvMatrix[heightPos][widthPos] = yuvBlock[j / blockDimension][j % blockDimension];
widthPos++;
if (widthPos >= width){
widthPos = (i * blockDimension) % width;
heightPos++;
}
if (widthPos == ((i + 1) * blockDimension) % width){
widthPos = (i * blockDimension) % width;
heightPos++;
}
}
if (heightPos == height ){
heightPos = heightPosTemp;
}
else {
heightPos = (i * blockDimension) % height;
}
widthPos = ((i + 1) * blockDimension) % width;
}
return yuvMatrix;
}
The method I used to break the matrix:
public List<long[][]> matrixToBlocks(long[][] yuvMatrix, int blockDimension, int width, int height){
int blocksSize = width / blockDimension * (height / blockDimension);
List<long[][]> blocks = new ArrayList<long[][]>();
for (int i = 0; i < blocksSize; i++) {
long[][] subBlock = new long[blockDimension][blockDimension];
int heightPos = (blockDimension * (i / blockDimension)) % height;
int widthPos = (blockDimension * i) % width;
if (widthPos + blockDimension > width) {
widthPos = 0;
}
for (int row = 0; row < blockDimension; row++) {
for (int col = 0; col < blockDimension; col++) {
subBlock[row][col] = yuvMatrix[heightPos + row][col + widthPos];
}
}
blocks.add(subBlock);
}
return blocks;
}
The way I tested it:
public static void testareMatBlo(int height, int width, int blockdim){
long[][] test = new long[height][width];
int val = 1;
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
test[i][j] = val;
val++;
}
}
List<long[][]> blocks = matrixToBlocks(test, blockdim, width, height);
long[][] matrix = blocksToMatrix(blocks, blockdim, width, height);
if (Arrays.deepEquals(test, matrix)){
System.out.println("YES");
}
else {
System.out.println("NO");
}
}
This works:
testareMatBlo(4, 4, 2);
But anything else doesn't. Can anyone explain what I did wrong?
I didn't thoroughly read your code for matrixToBlocks(...) but all those calculations like int blocksSize = width / blockDimension * (height / blockDimension); are very likely to introduce hard to spot errors - and you actually don't need them:
public static List<long[][]> matrixToBlocks(long[][] yuvMatrix, int blockDimension){
//Check matrix and block dimension match
if( yuvMatrix.length == 0 || yuvMatrix.length % blockDimension != 0
|| yuvMatrix[0].length == 0 || yuvMatrix[0].length % blockDimension != 0 ) {
throw new IllegalArgumentException("whatever message you like");
}
List<long[][]> blocks = new ArrayList<long[][]>();
//Iterate over the blocks in row-major order (down first, then right)
for( int c = 0; c < yuvMatrix.length; c += blockDimension ) {
for( int r = 0; r < yuvMatrix[c].length; r += blockDimension ) {
long[][] subBlock = new long[blockDimension][blockDimension];
//Iterate over the block in row-major order
for(int bc = 0; bc < blockDimension; bc++ ) {
for(int br = 0; br < blockDimension; br++ ) {
subBlock[bc][br]=yuvMatrix[c+bc][r+br];
}
}
blocks.add(subBlock);
}
}
return blocks;
}
That method doesn't look shorter but it is: discounting the preliminary check yours is missing there are only 8 actual lines of code compared to 13 in your code. That's not the point however. What's more important is that the logic is easier since there are only a few calculations involved (like c+bc).
You might think this is inefficient but it isn't: you're accessing each element only once and thus even though there are 4 nested loops the overall complexity is still O(n) with n being the size of the matrix.
Constructing the matrix back is equally easy. The major thing you need to take care of is the ordering of the blocks: if you create them in row-major order (blocks below each other are next to each other in the list) you need to recreate the matrix in the same way:
public static long[][] blocksToMatrix( List<long[][]> blocks, int width, int height ) {
long[][] yuvMatrix = new long[width][height];
int c = 0;
int r = 0;
for( long[][] block : blocks ) {
int blockWidth = block.length;
int blockHeight = block[0].length;
for( int bc = 0; bc < block.length; bc++ ) {
for( int br = 0; br < block[bc].length; br++ ) {
yuvMatrix[c + bc][r + br] = block[bc][br];
}
}
//calculate the next offset into the matrix
//The blocks where created in row-major order so we need to advance the offset in the same way
r += blockHeight;
if( r >= height ) {
r = 0;
c += blockWidth;
}
}
return yuvMatrix;
}
I need to fill a 2D Array with numbers between 2 and 6, given by the user (is just part of a bigger proyect) but when I give the number I only get another request for a number.
public static int[][] crearTablero(int tamaño)
{
int[][] tablero = new int[tamaño][tamaño];
return tablero;
}
public static void imprimeTablero(int[][] tablero)
{
for(int i = 0; i<tablero.length; i++)
{
for(int j = 0; j<tablero[i].length; j++)
{
System.out.print(tablero[i][j] + " ");
}
System.out.println();
}
}
public static void swap(int[][] tablero, int x1, int y1, int x2, int y2)
{
int temp = tablero[x1][y1];
tablero[x1][y1] = tablero[x2][y2];
tablero[x2][y2] = temp;
}
public static void rellenarTablero(int[][] tablero) {
for (int x = 0; x < tablero.length; x++) {
for (int y = 0; y < tablero[x].length; y++) {
tablero[x][y] = aleatorio(numeroColores());
}
}
}
public static void shuffleBoard(int[][] tablero)
{
Random rnd = new Random();
int randX = 0;
for(int x = 0; x<tablero.length; x++)
{
randX = rnd.nextInt(tablero.length);
int[] temp = tablero[x];
tablero[x] = tablero[randX];
tablero[randX] = temp;
}
}
public static int numeroColores(){
int colores = 0;
System.out.print("Numero de colores (entre 2 y 6): ");
Scanner scn = new Scanner(System.in);
colores = scn.nextInt();
while(colores < 2 || colores > 6)
{
System.out.println("Invalid matrix size. Re-enter ");
}
return colores;
}
public static int aleatorio(int colores) {
int l = (int) (Math.floor(Math.random()*(colores-2)) + 2);
return l;
}
I would really appreciate some help because I don't know how to continue, Thanks.
You call numeroColores() in a for-loop in a for-loop, so you are of course asked multiple times for it.
Btw. you have an endless loop if you type in 1 or smaller or 7 or bigger with constantly getting the same line printed out and not asking for new input
Try this code to generate the random value between 2 and 6
public static int aleatorio(int colores) {
int l = 0;
while(l < 2 || l > 6) {
l = (int) (Math.floor(Math.random()*(colores-2)) + 2);
}
return l;
}
This ImageBrightener method is supposed to brighten the image by increasing the color values. Each value should increase half the distance between it and 255. Thus, 155 would go to 205 while 205 would go to 230 and so on. Can anyone help figure out the issue with ImageBrightener! Thanks
import squint.SImage;
public class ImageBrightener implements ImageTransformer {
#Override
public SImage transform(SImage picture) {
return BrightenImage(picture);
}
private static SImage BrightenImage(SImage si) {
int[][] newReds = BrightenImageSingleChannel(si.getRedPixelArray());
int[][] newGreens = BrightenImageSingleChannel(si.getGreenPixelArray());
int[][] newBlues = BrightenImageSingleChannel(si.getBluePixelArray());
return new SImage(newReds, newGreens, newBlues);
}
// Here is the code to brighten the image and is not functioning properly
private static int[][] BrightenImageSingleChannel(int[][] pixelArray) {
private static int[][] BrightenImageSingleChannel(int[][] pixelArray) {
int columns = pixelArray.length;
int rows = pixelArray[0].length;
int[][] answer = new int[columns][rows];
for (int x = 0; x < columns; x++) {
for (int y = 0; y < rows; y++) {
answer[x][y] = 255 - pixelArray[x][y] ;
answer[x][y] = answer[x][y] + pixelArray[x][y] ;
}
}
return answer;
}
}
// Here is the properly functioning code for darkening my image.
private static int[][] DarkenImageSingleChannel(int[][] pixelArray) {
int columns = pixelArray.length;
int rows = pixelArray[0].length;
int[][] answer = new int[columns][rows];
for (int x = 0; x < columns; x++) {
for (int y = 0; y < rows; y++) {
answer[x][y] = (255 * 2) / 3 - pixelArray[x][y];
}
}
return answer;
}
}
The problem is here
answer[x][y] = 255 - pixelArray[x][y] ;
answer[x][y] = answer[x][y] + pixelArray[x][y] ;
answer[x][y] will always be 255.
Try this
answer[x][y] = (pixelArray[x][y] + 255) / 2;
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 ) )