JavaFX event handler for array - arrays

All this rectangles are added in grid and I want after click each of them to change the color to white, but program throwing and exception.
Can i do this with this way or I need to get the position of rectangle a make on his place a new one ?
Rectangle[] rec = new Rectangle[22 * 12];
for( int i = 0; i < 22 * 12; i++){
rec[i] = new Rectangle(32, 32);
rec[i].setStroke(Color.BLACK);
rec[i].setFill( Color.valueOf("#202020") );
rec[i].setStrokeWidth(1);
rec[i].setOnMouseClicked(e -> {
Rectangle r = new Rectangle(32, 32, Color.WHITE);
rec[i].setFill( Color.WHITE); // exception at this line -> i must be final or ...
});
}

As your compile error says, you can't access non-final variables in a lambda expression. You can get around this by putting your rectangle in a different (effectively-final) variable:
Rectangle[] rec = new Rectangle[22 * 12];
for( int i = 0; i < 22 * 12; i++){
Rectangle r = new Rectangle(32, 32);
r.setStroke(Color.BLACK);
r.setFill( Color.valueOf("#202020") );
r.setStrokeWidth(1);
r.setOnMouseClicked(e -> {
r.setFill( Color.WHITE);
});
rec[i] = r ;
}
}

Related

Changing plane geometry vectors in ThreeJS leaving behind connecting plane

// this method will be called once per frame
(plane as any).tick = (delta: number) => {
let pos = geometry.getAttribute("position");
let pa = pos.array as Float32Array;
let vectorArr : THREE.Vector3[] = [];
for (let i = 0; i < pa.length; i += 3) {
vectorArr.push(new THREE.Vector3(pa[i], pa[i + 1], pa[i + 2]));
}
for (let vect of vectorArr) {
vect.x -= 5 * delta;
if (vect.x < - 40) {
vect.x = 40;
removeArr.push(vect);
}
}
vectorArr.map((vect, i) => {
pa[3 * i] = vect.x;
pa[3 * i + 1] = vect.y;
pa[3 * i + 2] = vect.z;
});
pos.needsUpdate = true;
}
The above code is used for modifying the plane, I'm basically just trying to reset the vectors that are past x=-40, but that's leaving behind some sort of 'connecting plane' between the plane. Image below an example, the material is double sided(but changing it still leaves behind the weird connecting plane).
What it looks like normally, without the vector.x -= 5 * delta below.
I'm basically just trying to create an infinite scrolling landscape, so if you have a good way to do this in ThreeJS apart from my code, please let me know!

Draw an image from an array value p5.js

I am fairly new to p5.js, however I am trying to read a .txt file which contains the below text, and draw a picture depending on the value within the .txt file.
00000
20022
00222
22020
11111
I am currently stumped as to how to draw an image depending on the number in the array, as an example '1' would be grass. I have loaded the file in as a string using the following code: track = loadStrings("track1.txt");
I am trying to load it as a 5x5 'tile' if you will. Any help would be appreciated :)
I've used p5.Image to create a picture based on the pixels in the file.
This is a way of writing the code:
let track;
let colors;
let img;
function setup() {
createCanvas(100, 100);
track=loadStrings("track1.txt")
colors = [color(255,0,0),color(0,255,0),color(0,0,255)]
}
function draw() {
background(220);
img = createImage(track.length, track[0].length)
img.loadPixels();
for (let i = 0 ; i < track.length ; i++){
for (let j = 0 ; j < track.length ; j++){
img.set(i, j, colors[int(track[i][j])]);
}
}
img.updatePixels();
image(img, 50, 50);
}
Well you could probs split it up into arrays and also if you'd have some sort of seperator for colors, like: track1.txt: 10, 30, 255\n ... r, g, b\n .... Right now you would have to use the rgb rrrgggbbb
let colors = track.split("\n") // makes every new line into an array
for(let x = 0; x <= width; x ++) // "\n" = new line
for(let y = 0; y <= height; y ++){
let currentCol = []
for(let i = 0; i < 9; i += 3)
currentCol.push(
colors[x + y][0 + i] + // I'm really not sure about the: colors[x + y]...
colors[x + y][1 + i] +
colors[x + y][2 + i]
)
set(x, y, color(currentCol[0], currentCol[1], currentCol[2]))
}
I also made a function with a slightly different formula, which might work better, i am not sure though, but this is the actual formula to get from pixel array
function getColor(x, y, allColorsArr){
let _col = [] // current color, underscore not to accidentally clear your variable
for(let i = 0; i < 3; i ++)
_col.push(
allColorsArr[x + y * width][0 + i * 3] +
allColorsArr[x + y * width][1 + i * 3] +
allColorsArr[x + y * width][2 + i * 3]
)
return {
r: parseInt(_col[0], 10),
g: parseInt(_col[1], 10),
b: parseInt(_col[2], 10)
} // returning an object here just for the `.r`; `.g`; `.b`
} // you could do something like: let Colors = {red: 0, green: 1, blue: 2}
// col[Colors.red], col[Colors.green], col[Colors.blue] if you want
// example: let col = getColor(1, 0, track.split("\n"))
// example: stroke(col.r, col.g, col.b)
THERE IS MOST LIKELY IS A BETTER WAY TO DO THIS, but at least this works...

Generate an automatic complete graph in C# WPF application

I need to draw automatically a complete graph. the complete graph will depend on the number of nodes enter by the user. The weight between two nodes is assigned randomly. The method have used is inefficient because to draw a graph of nine nodes, the user has to click on the screen nine times. Moreover to draw an edge between two nodes, the user has to right click at most at two nodes to establish the link. I have tried to look for some online examples of this, but I cannot seem to find anything. This is what I have done so far
CODE
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Label v = new Label();
v.Content = E;
Ellipse cir = new Ellipse();
cir.Width = 16.5;
cir.Height = 16;
circ.Stroke = Brushes.MediumAquamarine;
circ.StrokeThickness = 2;
CanvasMiddle.Children.Add(circ);
Point a = e.GetPosition(circ);
Canvas.SetLeft(circ, a.X-3);
Canvas.SetTop(circle, a.Y+1);
Vertex.Add(i, new Tuple<double, double>(a.X, a.Y));
CanvasMiddle.Children.Add(value);
Point coordinates = e.GetPosition(v);
Canvas.SetLeft(v, coordinates.X-5);
Canvas.SetTop(va, coordinates.Y-5);
f++;
i++;
}
// To generate the edge between two nodes
private void Window_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
for (int i = 1; i <= Node.Count; i++)
{
E1 = Node[i].Item1 - 13; a2 = Node[i].Item1 + 13;
G1 = Node[i].Item2 - 13; b2 = Node[i].Item2 + 13;
if ((P >= E1 && P <= G1) && (Q >= E1 && Q <= G1))
{
ID1[j] = i;
j++;
if (j == 2)
{
Line li = new Line();
li.X1 = Vertex[ID1[0]].Item1 + 5;
li.Y1 = Vertex[ID1[0]].Item2 + 5;
li.X2 =(line.X2-13)+ (Vertex[ID1[1]].Item1 + 5);
li.Y2 =(line.Y2) + (Vertex[ID1[1]].Item2 + 5);
li.Stroke = Brushes.MediumAquamarine;
li.StrokeThickness = 2;
Point co1 = e.GetPosition(li);
Canvas.SetLeft(li, co1.X+2.78);
Canvas.SetTop(li, co1.Y+1.85);
CanvasMiddle.Children.Add(li);
j = 0;
}
Images:
Here is the link of the specific graph at hand.
http://i.stack.imgur.com/kJF5K.png

How to draw a zigzag line?

I am creating a document based application and i want to draw a horizontal line underlying the text. But, line should not be straight. i want to draw a line like this.
Currently i am using System.Graphics object to draw any object.
private void DrawLine(Graphics g, Point Location, int iWidth)
{
iWidth = Convert.ToInt16(iWidth / 2);
iWidth = iWidth * 2;
Point[] pArray = new Point[Convert.ToInt16(iWidth / 2)];
int iNag = 2;
for (int i = 0; i < iWidth; i+=2)
{
pArray[(i / 2)] = new Point(Location.X + i , Location.Y + iNag);
if (iNag == 0)
iNag = 2;
else
iNag = 0;
}
g.DrawLines(Pens.Black, pArray);
}
UPDATED:
Above code is working fine and line draws perfectly but, this code effects on application performance. Is there another way to do this thing.
If you want fast drawing just make a png image of the line you want, with width larger than you need and then draw the image:
private void DrawLine(Graphics g, Point Location, int iWidth)
{
Rectangle srcRect = new Rectangle(0, 0, iWidth, zigzagLine.Height);
Rectangle dstRect = new Rectangle(Location.X, Location.Y, iWidth, zigzagLine.Height);
g.DrawImage(zigzagLine, dstRect, srcRect, GraphicsUnit.Pixel);
}
zigzagLine is the bitmap.
valter

Last clicked image in array

I have an array of images, when i click on one of them, I want it to loop and create a pattern. (This part already works). When i want to get the last clicked image out of my array i get a 'NullPointerException'
PImage[] patronen = new PImage[7];
int pLength = patronen.length;
PImage selectedPatroon = patronen[patronen.length-1];
void setup(){
size(1024, 768);
}
void draw(){
createPGrid();
image(selectedPatroon, xPos, yPos);
}
void createPGrid(){
for(int j = 0; j < gpLength; j++){
// Grid maanmaken
xPos = xOffset + ((j % cols) * (size+padding));
yPos = yOffset + ((j / cols) * (size+padding));
// Thumbs
patronen[j] = loadImage( j + ".png");
image(patronen[j], xPos, yPos);
// Check if thumb is clicked
if((mouseX >= xPos && mouseX <= xPos+size) &&
(mouseY >= yPos && mouseY <= yPos+size)){
if (mousePressed){
// grid patronen
xPos = 0;
yPos = 0;
// Loop pattern
while( yPos < height ){
while( xPos < width ){
patronen[j] = loadImage(j + "groot" + ".png");
selectedPatroon = patronen[j]
xPos += 500;
}
yPos +=500;
xPos = 0;
}
rect(xPos, yPos, size, size);
}
}
}
}
EDIT: The thing is, it works perfectly without
PImage selectedPatroon = patronen[patronen.length-1];
but then the looped pattern comes above all my others functions. And i want it to be under that.
You are creating an array at the top of your code then setting an image to the last element in the array, but you're not populating the array first.
PImage[] patronen = new PImage[7]; <<< Blank 7 element array.
int pLength = patronen.length;
PImage selectedPatroon = patronen[patronen.length-1];
To answer the questions you've put in the comments, you cannot populate an array of PImages with ints, those are different variable types. Try something like this in setup():
PImage patronen = new PImage[7];
for(int i = 0; i < patronen.length; i++){
patronen[i] = loadImage("image" + i + ".png"); // or whatever format your filenames are
}
The loadImage(String name) function returns a PImage, so you can insert it directly into your array. Just trying to insert the numbers won't work because the computer doesn't know that the numbers represent the filename without you telling it with loadImage().

Resources