Javafx gridpane width setting - javafx

I need to make some kind of table in which I store simple Region nodes (I will do other stuff on them afterwards - such as megring cells horizontally and giving them other properties, Labels for example) Table will have lots of columns, >200. My goal is to force every grid to have the same width (very important) and to generate that table dynamically.
Here is part of my code that generates that table.
GridPane schedule = new GridPane();
for (int j = 0; j < horizontalGridCount; ++j) {
ColumnConstraints cc = new ColumnConstraints();
cc.setPercentWidth(100/horizontalGridCount);
schedule.getColumnConstraints().add(cc);
}
for (int i = 0; i < verticalGridCount; ++i) {
for (int j = 0; j < horizontalGridCount; ++j) {
final Region grid = new Region();
grid.setStyle("-fx-background-color: #dddddd;");
grid.setPrefHeight(30); // set to make regions visible on screen
grid.setPrefWidth(10); // set to make regions visible on screen
schedule.add(grid, j, i);
}
}
schedule.gridLinesVisibleProperty().set(true);
Here is the output I get on my screen. As you can observe some grids are close-grained then the others
Do you have any idea why it is that wrong and how to fix that?
P.S. It's my first post here, I hope I've done everything right ;)

You are using integer division logic, which rounds things. Use floating point logic instead:
cc.setPercentWidth(100.0/horizontalGridCount);
Note the 100.0 which makes 100.0 (and the division result) a non-integer.
Also don't set the grid lines visible in your target app, that setting is only for debugging (I guess this is why you have it there and set to true, but just a reminder in case):
schedule.gridLinesVisibleProperty().set(true);
If you want borders on your grid cells you can review this demo program.

Related

CS50, Pset 4, filter-less, reflection issues

so im currently trying to do the less comfortable pset 4 and have just got to the reflection part.
My code seems to work with the examples provided but fails the CS50 Check, I believe its something to do with my logic that i just cant get my head around. Maybe to do with the fact ive not actually done anything regarding whether the width is even or odd.
Also I originally tried to put the * pointer on the "image[i][j]" parts but that didnt work so then decided to do it on the "temp" part and discovered I had to use "malloc". Im not sure why this is the case as in the lecture its the variables we want changing and not the temporary variable that was assigned a pointer, any explanation towards that would also be appreciated.
I've also never used this site before so apologies if this doesnt make sense.
PG x
edit: I've also just realise it 'works' on the images provided even if there are no pointers.
edit: I saw on another question that doing "image[i][width -1 - j]" works, so now it passes the check but im not sure why its a "-1", is it because arrays start at [0] ?
void reflect(int height, int width, RGBTRIPLE image[height][width])
for (int i = 0; i < height; i++)
{
//width / 2 as we swap half the picture with the other half (unless its an uneven width?! :O)
for (int j = 0; j < width / 2; j++)
{
//first pixel = last pixel
//the * means that we are going to the LOCATION of temp in memory rather than just the value itself
RGBTRIPLE *temp = malloc(sizeof(RGBTRIPLE));
*temp = image[i][j];
image[i][j] = image[i][width -j];
image[i][width - j] = *temp;
free(temp);
}
}

How do I force gridLayout to make each cell the same size? Also how do I get rid off unnecessary spacing?

The application
As you can see it doesn't make the pushButtons equally big. Even though I created them with these properties
butt->setMaximumHeight(50);
butt->setMaximumWidth(50);
butt->setMinimumHeight(50);
butt->setMinimumWidth(50);
to make sure they have the exact size I want.
This is the part of my code where I create my buttons:
for (int r = 0; r < 10; r++){
for (int c = 0; c < 10; c++)
{
QPushButton *butt = new QPushButton();
butt->setMaximumHeight(50);
butt->setMaximumWidth(50);
butt->setMinimumHeight(50);
butt->setMinimumWidth(50);
ui->gridLayout->addWidget(butt, r, c);
gameTable[r][c] = butt;
}
}
Here, gameTable is defined as following:
QPushButton *gameTable[10][10];
Also, as you can see, there are spaces between the columns. How do I get rid off them?
To make gridLayout behave as intended, it is necessary to set size constraint to fixed:
ui->gridLayout->setSizeConstraint(QLayout::SetFixedSize);

Processing 3.0.1: Best way to scroll RSS feed

I am new to Processing and I am trying to start small by combining some of the built-in examples. I am scrolling an RSS feed from Google News over an image. It seems to work just fine but the code is limited to scrolling one headline at a time. What if I want to limit the space between each headline? I thought of two ways to do this: the first is to headlines into a really long string. The second is to make two headlines scroll at once. The problem with the second method is that, if I move on to bigger images or start scrolling smaller strings (like stock quotes), I will need to have many statements for scrolling many headlines. Is there a better way that I am not thinking of?
/**
* Scrolling Rss Feeds
*
* Scroll headlines from Google News on top of an image
*/
PImage img; // Declare variable "a" of type PImage
float x; // horizontal location of headline
XML xml;
String[] headlines;
int index = 0;
void setup() {
size(640, 360);
x = width;
// The image file must be in the data folder of the current sketch
// to load successfully
img = loadImage("moonwalk.jpg"); // Load the image into the program
// The URL for the XML document
String url = "http://news.google.com/news?cf=all&hl=en&pz=1&ned=us&output=rss";
// Load the XML document
xml = loadXML(url);
// Grab the element we want
XML[] headers = xml.getChildren("channel/item/title");
headlines = new String[headers.length];
for (int i = 0; i < headers.length; i++) {
headlines[i] = headers[i].getContent();
}
}
void draw() {
// Displays the image at its actual size at point (0,0)
image(img, 0, 0);
textSize(32);
text(headlines[index], x, 90);
x = x - 3;
float w = textWidth(headlines[index]);
if (x < -w) {
x = width;
index = (index + 1) % headlines.length;
}
}

Array grid with click functions in Processing

I have a grid that is clickable but I am unsure how to proceed with a certain set of rules.
Edit: I rewrote the rules in a more understandable fashion. Very similar to that of the game of life.
Setup
21 cells across / columns
10 cells down / rows
4 base cells vertically aligned in the centre of the board.
Outline cells will surround the base cells.
Every other cell begins as inactive.
Base Cells [2]
Constant and active blue cells in the middle, which cannot be removed.
Active [0] -> [1]
When clicked, an inactive white cell becomes black
if
the edge touches the edge of a base cell
or
the edge touches the edge of another active cell
(either to the left, right, top or bottom – not diagonally.)
else
remain inactive
Inactive [1] -> [0]
When clicked, an active black cell returns to white.
Outline [3]
A series of yellow cells that will constantly update to surround the neighborhood of active cells.
Could anyone help me in achieving this, I would appreciate comments to help me understand the process.
Here is my current code:
int boxsize = 100;
int cols, rows;
color[][] colors;
int saved_i = -1;
int saved_j = -1;
void setup() {
size(1300, 600);
cols = width/boxsize;
rows = height/boxsize;
colors = new color[cols][rows];
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
colors[i][j] = color(255);
}
}
}
void draw() {
background(255);
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
fill(colors[i][j]);
rect(i*boxsize, j*boxsize, boxsize, boxsize);
}
}
}
void mousePressed() {
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
int x = i*boxsize;
int y = j*boxsize;
if (mouseX > x && mouseX < (x + boxsize) && mouseY > y && mouseY < (y + boxsize)) {
if ( saved_i == -1 || saved_i == i || saved_j == j ) {
colors[i][j] = color(0);
if (j>0) colors[i][j-1]=color(255, 255, 0);
if (j>0) colors[i+1][j-1]=color(255, 255, 0);
if (j<rows-1) colors[i][j+1]=color(255, 255, 0);
if (j<rows-1) colors[i+1][j+1]=color(255, 255, 0);
if (i>0) colors[i-1][j]=color(255, 255, 0);
if (i>0) colors[i-1][j-1]=color(255, 255, 0);
if (i>0) colors[i-1][j+1]=color(255, 255, 0);
if (i<cols-1) colors[i+1][j]=color(255, 255, 0);
saved_i = i;
saved_j = j;
}
}
}
}
}
Your question is pretty broad, so I'll answer in broad terms. You need to figure out four things:
How to represent your cells. In other words, what type of variable you want to store your grid in. You're using colors now, but you probably don't want to do it that way. The way I see it, you have three logical options:
Use a 2D array of enum values. The enum would have states for BASE, ACTIVE, INACTIVE, and OUTLINE. This is probably the correct way to go.
Use a 2D array of ints. 0 for base, 1 for active, 2 for inactive, 3 for outline. Using an enum is probably better, but this is probably easier for a novice to understand.
Use a 2D array of objects. Create a class that represents a cell, and the object would store its state (in either an enum or an int). You would use this approach if you wanted other logic inside each cell, or maybe if you wanted each cell to keep track of its own neighbors.
How to change the state of a single cell on mouse click. You've got logic that deals with colors, now you just have to apply that logic to the data structure you choose in step 1. Maybe create a function that takes mouseX and mouseY and returns the position in the array at that location.
How to get the new state for each cell for the next generation. Create a function that takes the position of one cell (its row and column in the 2D array) and returns the state that the cell should have in the next generation. This is the "meat and potatoes" of your project, and separating it out will help you isolate the logic. Get out a piece of grid paper and draw some examples. If you know the position of a cell, what are the positions of its neighbors? There are a ton of tutorials on the Game of Life out there that will have this logic.
How to update your grid. Remember that you have to do step 2 to every cell in the grid before you update the whole grid. This means that you have to make a new 2D array each iteration.
Break your problem down down like this, and post a new question if you get stuck on a particular step. It's hard to help with general "how do I do this" type questions. It's much easier to help with more specific questions like "I tried X, expected Y, but got Z instead. What am I doing wrong?"
Good luck!

CSG operations on implicit surfaces with marching cubes

I render isosurfaces with marching cubes, (or perhaps marching squares as this is 2D) and I want to do set operations like set difference, intersection and union. I thought this was easy to implement, by simply choosing between two vertex scalars from two different implicit surfaces, but it is not.
For my initial testing, I tried with two spheres circles, and the set operation difference. i.e A - B. One circle is moving and the other one is stationary. Here's the approach I tried when picking vertex scalars and when classifying corner vertices as inside or outside. The code is written in C++. OpenGL is used for rendering, but that's not important. Normal rendering without any CSG operations does give the expected result.
void march(const vec2& cmin, //min x and y for the grid cell
const vec2& cmax, //max x and y for the grid cell
std::vector<vec2>& tri,
float iso,
float (*cmp1)(const vec2&), //distance from stationary circle
float (*cmp2)(const vec2&) //distance from moving circle
)
{
unsigned int squareindex = 0;
float scalar[4];
vec2 verts[8];
/* initial setup of the grid cell */
verts[0] = vec2(cmax.x, cmax.y);
verts[2] = vec2(cmin.x, cmax.y);
verts[4] = vec2(cmin.x, cmin.y);
verts[6] = vec2(cmax.x, cmin.y);
float s1,s2;
/**********************************
********For-loop of interest******
*******Set difference between ****
*******two implicit surfaces******
**********************************/
for(int i=0,j=0; i<4; ++i, j+=2){
s1 = cmp1(verts[j]);
s2 = cmp2(verts[j]);
if((s1 < iso)){ //if inside circle1
if((s2 < iso)){ //if inside circle2
scalar[i] = s2; //then set the scalar to the moving circle
} else {
scalar[i] = s1; //only inside circle1
squareindex |= (1<<i); //mark as inside
}
}
else {
scalar[i] = s1; //inside neither circle
}
}
if(squareindex == 0)
return;
/* Usual interpolation between edge points to compute
the new intersection points */
verts[1] = mix(iso, verts[0], verts[2], scalar[0], scalar[1]);
verts[3] = mix(iso, verts[2], verts[4], scalar[1], scalar[2]);
verts[5] = mix(iso, verts[4], verts[6], scalar[2], scalar[3]);
verts[7] = mix(iso, verts[6], verts[0], scalar[3], scalar[0]);
for(int i=0; i<10; ++i){ //10 = maxmimum 3 triangles, + one end token
int index = triTable[squareindex][i]; //look up our indices for triangulation
if(index == -1)
break;
tri.push_back(verts[index]);
}
}
This gives me weird jaggies:
(source: mechcore.net)
It looks like the CSG operation is done without interpolation. It just "discards" the whole triangle. Do I need to interpolate in some other way, or combine the vertex scalar values? I'd love some help with this.
A full testcase can be downloaded HERE
EDIT: Basically, my implementation of marching squares works fine. It is my scalar field which is broken, and I wonder what the correct way would look like. Preferably I'm looking for a general approach to implement the three set operations I discussed above, for the usual primitives (circle, rectangle/square, plane)
EDIT 2: Here are some new images after implementing the answerer's whitepaper:
1.Difference
2.Intersection
3.Union
EDIT 3: I implemented this in 3D too, with proper shading/lighting:
1.Difference between a greater sphere and a smaller sphere
2.Difference between a greater sphere and a smaller sphere in the center, clipped by two planes on both sides, and then union with a sphere in the center.
3.Union between two cylinders.
This is not how you mix the scalar fields. Your scalars say one thing, but your flags whether you are inside or not say another. First merge the fields, then render as if you were doing a single compound object:
for(int i=0,j=0; i<4; ++i, j+=2){
s1 = cmp1(verts[j]);
s2 = cmp2(verts[j]);
s = max(s1, iso-s2); // This is the secret sauce
if(s < iso) { // inside circle1, but not inside circle2
squareindex |= (1<<i);
}
scalar[i] = s;
}
This article might be helpful: Combining CSG modeling with soft blending using
Lipschitz-based implicit surfaces.

Resources