How do I make this text display on the screen on the click of a button? - button

let img
let img2
let img3;
let img4
let img5
function preload(){
img = loadImage("Barb1.png");
img2 = loadImage("Barb2.png");
img3 = loadImage("Barb3.png");
img4 = loadImage("Barb4.png");
img5 = loadImage("Barb5.png");
}
function setup() {
createCanvas(1500, 1500);
scene = 1;
ButtonA = createButton("A. GOOD");
ButtonA.position(20,640);
ButtonA.size(100,50)
ButtonA.mouseClicked(correct0);
ButtonB = createButton("B. PINEAPPLE");
ButtonB.position(20,700);
ButtonB.size(100,50)
ButtonB.mouseClicked(incorrect);
ButtonC = createButton("C. PLEASE KILL ME");
ButtonC.position(20,760);
ButtonC.size(100,50)
ButtonC.mouseClicked(incorrect);
ButtonD = createButton("A. BAD");
ButtonD.position(20,640);
ButtonD.size(100,50)
ButtonD.mouseClicked(incorrect);
ButtonD.hide();
ButtonE = createButton("B. PINEAPPLE");
ButtonE.position(20,700);
ButtonE.size(100,50)
ButtonE.mouseClicked(correct1);
ButtonE.hide();
ButtonF = createButton("C. PLEASE KILL ME");
ButtonF.position(20,760);
ButtonF.size(100,50)
ButtonF.mouseClicked(incorrect);
ButtonF.hide();
ButtonG = createButton("1. Delicious");
ButtonG.position(20,640);
ButtonG.size(100,50)
ButtonG.mouseClicked(incorrect);
ButtonG.hide();
ButtonH = createButton("2. Rainy");
ButtonH.position(20,700);
ButtonH.size(100,50)
ButtonH.mouseClicked(correct2);
ButtonH.hide();
ButtonI = createButton("3. Red!");
ButtonI.position(20,760);
ButtonI.size(100,50)
ButtonI.mouseClicked(incorrect);
ButtonI.hide();
ButtonJ = createButton("1. My name is __!");
ButtonJ.position(20,640);
ButtonJ.size(100,50)
ButtonJ.mouseClicked(correct3);
ButtonJ.hide();
ButtonK = createButton("2. Carpe Diem!");
ButtonK.position(20,700);
ButtonK.size(100,50)
ButtonK.mouseClicked(incorrect);
ButtonK.hide();
ButtonL = createButton("3. I don't know yet, what's yours?");
ButtonL.position(20,760);
ButtonL.size(100,50)
ButtonL.mouseClicked(incorrect);
ButtonL.hide();
ButtonM = createButton("1. Goodbye Barb!");
ButtonM.position(20,640);
ButtonM.size(100,50)
ButtonM.mouseClicked(correct4);
ButtonM.hide();
ButtonN = createButton("2. Hello. Barb!");
ButtonN.position(20,700);
ButtonN.size(100,50)
ButtonN.mouseClicked(incorrect);
ButtonN.hide();
ButtonO = createButton("1. THANK THE LORD, IT'S OVER!");
ButtonO.position(20,760);
ButtonO.size(100,50)
ButtonO.mouseClicked(incorrect);
ButtonO.hide();
homebutton = createButton("HOME");
homebutton.position(395, 405);
homebutton.size(150,150);
homebutton.mousePressed(goHome);
homebutton.hide();
}
function correct0(){
print("Barb says,'Good job!' Hold left click and '2' to advance'")
}
function correct1(){
print("Barb says, 'Good job!' Hold left click and '3' to advance'");
}
function correct2(){
print("Barb says, 'Good job!' Hold left click and '4' to advance'");
}
function correct3(){
print("Barb says, 'Good job!' Hold left click and '5' to advance'");
}
function correct4(){
print("Barb says, 'Good job!' Hold left click and '6' to advance'");
}
function incorrect(){
print("Barb says, 'Hmm...that response to my question does not make sense, please try again!''");
}
function goHome(){
window.open('https://editor.p5js.org/PragyaKumari2/sketches/3fhigQjLg');
}
function draw() {
background(100,200,300);
if(scene ==1){
image(img,0,0,800,600)
text("Read the options out loud and choose your answer, make sure to check the console for BARB's reply!", 10, 620)
textSize(19);
if(keyIsPressed){
if(key ==2){
scene =2
ButtonA.remove();
ButtonB.remove();
ButtonC.remove();
ButtonD.show();
ButtonE.show();
ButtonF.show();
}
}
}
if(scene ==2){
image(img2,0,0,800,600)
text("Read the options loudly and choose your answer!", 50, 620)
textSize(20);
if(keyIsPressed){
if(key ==3){
scene =3
ButtonD.remove();
ButtonE.remove();
ButtonF.remove();
ButtonG.show();
ButtonH.show();
ButtonI.show();
}
}
}
if(scene == 3){
image(img3,0,0,800,600)
text("Read the options loudly and choose your answer!", 50, 620)
textSize(20);
if(keyIsPressed){
if(key ==4){
scene =4
ButtonG.remove();
ButtonH.remove();
ButtonI.remove();
ButtonJ.show();
ButtonK.show();
ButtonL.show();
}
}
}
if(scene ==4){
image(img4,0,0,800,600)
text("Read the options loudly and choose your answer!", 50, 620)
textSize(20);
if(keyIsPressed){
if(key ==5){
scene =5
ButtonJ.remove();
ButtonK.remove();
ButtonL.remove();
ButtonM.show();
ButtonN.show();
ButtonO.show();
}
}
}
if(scene == 5){
image(img5, 0,0, 800,600)
text("Read the options loudly and choose your answer!", 50, 620)
textSize(20);
if(keyIsPressed){
if(key ==6){
scene =6
ButtonM.remove();
ButtonN.remove();
ButtonO.remove();
homebutton.show();
}
}
}
if(scene == 6){
text("Thanks a lot for playing! Make sure to practice speaking!", 200, 375)
textSize(20);
}
}
I am able to print to the main console terminal, but I do not know how to print to the display screen. Ive tried using the text function, but it does not appear at all. I am also not that familiar with p5js, so I am stuck on this problem. Is there a problem with the function? Do I need to do something else to output the text? Is it an issue with the scene function I implemented?

I've created a global variable msg to keep the message you want to show to the user. So after next calling of the draw function, you can show it by text function if it has any value.
Also your code needs to set textAlign.
let img;
let img2;
let img3;
let img4;
let img5;
let msg;
function preload() {
img = loadImage("Barb1.png");
img2 = loadImage("Barb2.png");
img3 = loadImage("Barb3.png");
img4 = loadImage("Barb4.png");
img5 = loadImage("Barb5.png");
}
function setup() {
createCanvas(1500, 1500);
scene = 1;
ButtonA = createButton("A. GOOD");
ButtonA.position(20, 640);
ButtonA.size(100, 50);
ButtonA.mouseClicked(correct0);
ButtonB = createButton("B. PINEAPPLE");
ButtonB.position(20, 700);
ButtonB.size(100, 50);
ButtonB.mouseClicked(incorrect);
ButtonC = createButton("C. PLEASE KILL ME");
ButtonC.position(20, 760);
ButtonC.size(100, 50);
ButtonC.mouseClicked(incorrect);
ButtonD = createButton("A. BAD");
ButtonD.position(20, 640);
ButtonD.size(100, 50);
ButtonD.mouseClicked(incorrect);
ButtonD.hide();
ButtonE = createButton("B. PINEAPPLE");
ButtonE.position(20, 700);
ButtonE.size(100, 50);
ButtonE.mouseClicked(correct1);
ButtonE.hide();
ButtonF = createButton("C. PLEASE KILL ME");
ButtonF.position(20, 760);
ButtonF.size(100, 50);
ButtonF.mouseClicked(incorrect);
ButtonF.hide();
ButtonG = createButton("1. Delicious");
ButtonG.position(20, 640);
ButtonG.size(100, 50);
ButtonG.mouseClicked(incorrect);
ButtonG.hide();
ButtonH = createButton("2. Rainy");
ButtonH.position(20, 700);
ButtonH.size(100, 50);
ButtonH.mouseClicked(correct2);
ButtonH.hide();
ButtonI = createButton("3. Red!");
ButtonI.position(20, 760);
ButtonI.size(100, 50);
ButtonI.mouseClicked(incorrect);
ButtonI.hide();
ButtonJ = createButton("1. My name is __!");
ButtonJ.position(20, 640);
ButtonJ.size(100, 50);
ButtonJ.mouseClicked(correct3);
ButtonJ.hide();
ButtonK = createButton("2. Carpe Diem!");
ButtonK.position(20, 700);
ButtonK.size(100, 50);
ButtonK.mouseClicked(incorrect);
ButtonK.hide();
ButtonL = createButton("3. I don't know yet, what's yours?");
ButtonL.position(20, 760);
ButtonL.size(100, 50);
ButtonL.mouseClicked(incorrect);
ButtonL.hide();
ButtonM = createButton("1. Goodbye Barb!");
ButtonM.position(20, 640);
ButtonM.size(100, 50);
ButtonM.mouseClicked(correct4);
ButtonM.hide();
ButtonN = createButton("2. Hello. Barb!");
ButtonN.position(20, 700);
ButtonN.size(100, 50);
ButtonN.mouseClicked(incorrect);
ButtonN.hide();
ButtonO = createButton("1. THANK THE LORD, IT'S OVER!");
ButtonO.position(20, 760);
ButtonO.size(100, 50);
ButtonO.mouseClicked(incorrect);
ButtonO.hide();
homebutton = createButton("HOME");
homebutton.position(395, 405);
homebutton.size(150, 150);
homebutton.mousePressed(goHome);
homebutton.hide();
}
function correct0() {
msg = "Barb says,'Good job!' Hold left click and '2' to advance'";
}
function correct1() {
msg = "Barb says, 'Good job!' Hold left click and '3' to advance'";
}
function correct2() {
msg = "Barb says, 'Good job!' Hold left click and '4' to advance'";
}
function correct3() {
msg = "Barb says, 'Good job!' Hold left click and '5' to advance'";
}
function correct4() {
msg = "Barb says, 'Good job!' Hold left click and '6' to advance'";
}
function incorrect() {
msg =
"Barb says, 'Hmm...that response to my question does not make sense, please try again!''";
}
function goHome() {
window.open("https://editor.p5js.org/PragyaKumari2/sketches/3fhigQjLg");
}
function draw() {
background(100, 200, 300);
if (scene == 1) {
image(img, 0, 0, 800, 600);
text(
"Read the options out loud and choose your answer, make sure to check the console for BARB's reply!",
10,
620
);
textSize(19);
if (keyIsPressed) {
if (key == 2) {
scene = 2;
ButtonA.remove();
ButtonB.remove();
ButtonC.remove();
ButtonD.show();
ButtonE.show();
ButtonF.show();
}
}
}
if (scene == 2) {
image(img2, 0, 0, 800, 600);
text("Read the options loudly and choose your answer!", 50, 620);
textSize(20);
if (keyIsPressed) {
if (key == 3) {
scene = 3;
ButtonD.remove();
ButtonE.remove();
ButtonF.remove();
ButtonG.show();
ButtonH.show();
ButtonI.show();
}
}
}
if (scene == 3) {
image(img3, 0, 0, 800, 600);
text("Read the options loudly and choose your answer!", 50, 620);
textSize(20);
if (keyIsPressed) {
if (key == 4) {
scene = 4;
ButtonG.remove();
ButtonH.remove();
ButtonI.remove();
ButtonJ.show();
ButtonK.show();
ButtonL.show();
}
}
}
if (scene == 4) {
image(img4, 0, 0, 800, 600);
text("Read the options loudly and choose your answer!", 50, 620);
textSize(20);
if (keyIsPressed) {
if (key == 5) {
scene = 5;
ButtonJ.remove();
ButtonK.remove();
ButtonL.remove();
ButtonM.show();
ButtonN.show();
ButtonO.show();
}
}
}
if (scene == 5) {
image(img5, 0, 0, 800, 600);
text("Read the options loudly and choose your answer!", 50, 620);
textSize(20);
if (keyIsPressed) {
if (key == 6) {
scene = 6;
ButtonM.remove();
ButtonN.remove();
ButtonO.remove();
homebutton.show();
}
}
}
if (scene == 6) {
text("Thanks a lot for playing! Make sure to practice speaking!", 200, 375);
textSize(20);
}
textAlign(CENTER);
text(msg, width / 2, height / 2);
}

Related

scale konva image from the center and hold position on redraw

Hey guys I have a slight problem here I have a Konva.js app which is working pretty well. I have this function called SET_STAGE_DATA that is supposed to save the images current position on the canvas so it can be redrawn when the canvas disapears. It works but when you scale the image from the left the image shifts. I am not sure how to fix this. I thought I may be able to fix it with offset but to no avail.
Heres my SET_STAGE_DATA function
[SET_STAGE_DATA](state){
const isStage = state.stage;
if(isStage){
const groups = state.stage.find("Group");
const stageData = [];
for (let x = 0; x < groups.length; x++) {
let g = groups[x];;
let i = g.findOne("Image").getAttrs();
let position = g.findOne("Image").position();
console.log("this is position", position);
let group = { x: g.getX(), y: g.getY() };
let image = { x: i.width, y: i.height, position };
let obj = { image, group };
stageData.push(obj);
}
I use the stageData just before I build the image like so
let groupPos;
let imagePos;
if(state.stageData){
console.log(true);
for(let i =0; i<state.stageData.length; i++){
imageObj.width = state.stageData[i].image.x;
imageObj.height = state.stageData[i].image.y;
imagePos = state.stageData[i].position;
groupPos = state.stageData[i].group;
}
} else {
groupPos = {
x: state.stage.width() / 2 - imageObj.width / 2,
y: state.stage.height() / 2 - imageObj.height / 2
};
}
console.log("data", {groupPos, image: {width: imageObj.width, height: imageObj.height}});
const image = new Konva.Image({
image: imageObj,
width: imageObj.width,
height: imageObj.height,
strokeWidth: 10,
stroke: "blue",
strokeEnabled: false
});
if(imagePos){
image.position(imagePos)
}
const group = new Konva.Group({
draggable: true,
x: groupPos.x,
y: groupPos.y
});
I also have the typical update function found in the documentation:
function update(activeAnchor) {
const group = activeAnchor.getParent();
let topLeft = group.get(".topLeft")[0];
let topRight = group.get(".topRight")[0];
let bottomRight = group.get(".bottomRight")[0];
let bottomLeft = group.get(".bottomLeft")[0];
let image = group.get("Image")[0];
let anchorX = activeAnchor.getX();
let anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case "topLeft":
topRight.y(anchorY);
bottomLeft.x(anchorX);
break;
case "topRight":
topLeft.y(anchorY);
bottomRight.x(anchorX);
break;
case "bottomRight":
bottomLeft.y(anchorY);
topRight.x(anchorX);
break;
case "bottomLeft":
bottomRight.y(anchorY);
topLeft.x(anchorX);
break;
}
// image.position(topLeft.position());
let width = topRight.getX() - topLeft.getX();
let height = bottomLeft.getY() - topLeft.getY();
if (width && height) {
image.width(width);
image.height(height);
}
}
function addAnchor(group, x, y, name) {
let anchor = new Konva.Circle({
x: x,
y: y,
stroke: "#666",
fill: "#ddd",
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on("dragmove", function() {
update(this);
state.layer.draw();
});
anchor.on("mousedown touchstart", function() {
group.draggable(false);
this.moveToTop();
});
anchor.on("dragend", function(evt) {
group.draggable(true);
commit(SET_STAGE_DATA);
dispatch(UPDATE_ANIMATION, state.selectedNode);
state.layer.draw();
});
// add hover styling
anchor.on("mouseover", function() {
document.body.style.cursor = "pointer";
this.strokeWidth(4);
state.layer.draw();
});
anchor.on("mouseout", function() {
document.body.style.cursor = "default";
this.strokeWidth(2);
state.layer.draw();
});
group.add(anchor);
}
state.layer.draw();
},
when I scale to the left the image goes outside of the anchors on redraw. I know I can fix this visually as long as I don't redraw the image by doing image.position(topLeft.position()); as you can see is commented out but it always acts as if positioning isn't set if you drag from the left. If I scale from the bottom right everything is fine. it acts as though it goes back to the previous position of the images left top corrner but from what I understand using stage.find() will give you the current stage. I'm at a totally loss.
See in the image how it does not stay in the box. Any help here would be great thanks.
[1]: https://i.stack.imgur.com/HEfHP.jpg
Update the SET_STAGE_DATA function to look like this
[SET_STAGE_DATA](state){
const isStage = state.stage;
const isEditorMode = state.editorMode;
if(isStage && !isEditorMode){
const groups = state.stage.find("Group");
const stageData = [];
for (let x = 0; x < groups.length; x++) {
let g = groups[x];
let i = g.findOne("Image").getAttrs();
let group = {x: g.getX() + i.x, y: g.getY() + i.y };
let image = i;
let obj = { image, group };
stageData.push(obj);
}
state.stageData = stageData;
} else {
state.stageData = null;
}
}
group.x and y don't update on scale but image.x and y do. On move image x and y are 0 and if you add them to the group.x and y it will put the anchors where you need them to be.

In Javafx how to set the size cells of a gridpane a fraction of the parent pane?

I try to create a gridPane in JavaFx with a circle in it.I want the gridPane cells to use all the available space in the gridPane.(The GridPane is in the Center of a BorderPane) but the cells keep resizing to the dimensions of the inner objects.How do I get the cells to use all space available? (and how do I set the radius of the circle to a fraction of the space available in the Center of the BorderPane.
I am quite new to JavaFx but I tried to use Columnconstraints and RowConstraints to match my need. It didn't work.I tried also to bind the size of my objects in the GridPane to use a fraction of the stage size but it does not work properly as it does not correspond to the plane in the BorderPane.
public void start(Stage primaryStage) throws Exception{
BorderPane applicationLayout = new BorderPane();
primaryStage.setTitle("Multi-level feedback simulator");
Scene scene = new Scene(applicationLayout, 600, 600);
primaryStage.setScene(scene);
//Add the menu Bar
//MainMenuBar menuBar = new MainMenuBar(primaryStage);
//applicationLayout.setTop(menuBar);
//Add the main zone of drawing
TreeDrawingZone treeDrawingZone = new TreeDrawingZone(primaryStage,applicationLayout,3,3);
applicationLayout.setCenter(treeDrawingZone);
primaryStage.show();
primaryStage.setMaximized(true);
}
The GridPane code with the constraints.
The biggest part of the constructor creates lines dans circles to display a tree.
The drawings functions are createLine() and createCircle()
public class TreeDrawingZone extends Parent {
private GridPane drawingZoneLayout;
private Stage stage;
private int columnNumber;
private int rowNumber;
private Pane rootPane;
private List<Pair<Integer,Integer>> circlePositions;
public TreeDrawingZone(Stage stage,Pane rootPane, int treeHeight, int childrenPerNode){
this.stage = stage;
drawingZoneLayout = new GridPane();
columnNumber = 2*(int)Math.pow(childrenPerNode,treeHeight-1)-1;
rowNumber = 2*treeHeight-1;
circlePositions = new ArrayList<>();
this.rootPane = rootPane;
//TODO Use the correct height of the borderLayout (maybe with a upper level layout)
System.out.println(columnNumber);
System.out.println(rowNumber);
//column Constraints
for(int i = 1 ; i <= columnNumber ; i++){
ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setPercentWidth((double) 100/columnNumber);
columnConstraints.setFillWidth(true);
drawingZoneLayout.getColumnConstraints().add(columnConstraints);
}
//row Constraints
for(int i = 1 ; i <= rowNumber ; i++){
RowConstraints rowConstraints = new RowConstraints();
rowConstraints.setPercentHeight((double) 100/rowNumber);
rowConstraints.setFillHeight(true);
drawingZoneLayout.getRowConstraints().add(rowConstraints);
}
//Tree Representation
//Base Line
List<Integer> circleLineRepartition = new ArrayList<>();
for(int i = 0 ; i < columnNumber; i ++){
if(i % 2 == 0){
circleLineRepartition.add(i);
}
}
System.out.println(circleLineRepartition);
//Creation of the grid line per line
for(int i = rowNumber-1 ; i >=0 ; i-=2){
if(i % 2 == 0) {
//Case of the line with circles
for (Integer circlePosition : circleLineRepartition) {
Pane circlePane;
if (i == 0) {
circlePane = createCircle(true, false);
} else if (i == rowNumber - 1) {
circlePane = createCircle(false, true);
} else {
circlePane = createCircle();
}
drawingZoneLayout.add(circlePane, circlePosition, i);
circlePositions.add(new Pair<>(circlePosition, i));
}
List<Integer> upperCircleLineRepartition;
//Create the lines
//The following block enumerates the different cases to create the lines between the dotes
try {
upperCircleLineRepartition = getoddlyRepartedCenters(childrenPerNode, circleLineRepartition);
if (i > 0) {
int minPosition = circleLineRepartition.get(0);
int maxPosition = circleLineRepartition.get(circleLineRepartition.size() - 1);
int position = 0;
boolean drawHorizontal = true;
int linkedNodeCount = 0;
for (int j = minPosition; j <= maxPosition; j++) {
Pane linesPane;
if (j == circleLineRepartition.get(position) && minPosition != maxPosition) {
//Update the number of linked Nodes
if(drawHorizontal) {
linkedNodeCount += 1;
if(linkedNodeCount == childrenPerNode)
drawHorizontal = false;
}else{
linkedNodeCount = 1;
drawHorizontal = true;
}
//First element
if (linkedNodeCount == 1) {
if(upperCircleLineRepartition.contains(j)){
linesPane = createLines(LineDirection.NORTH,LineDirection.SOUTH,LineDirection.EAST);
}else {
linesPane = createLines(LineDirection.SOUTH, LineDirection.EAST);
}
}
//Last element
else if (linkedNodeCount == childrenPerNode) {
if(upperCircleLineRepartition.contains(j)){
linesPane = createLines(LineDirection.NORTH,LineDirection.SOUTH,LineDirection.WEST);
}else {
linesPane = createLines(LineDirection.WEST, LineDirection.SOUTH);
}
}//bridge with under and upper level
else if(upperCircleLineRepartition.contains(j)) {
linesPane = createLines(LineDirection.SOUTH, LineDirection.NORTH, LineDirection.EAST, LineDirection.WEST);
}
//other children
else{
linesPane = createLines(LineDirection.SOUTH, LineDirection.EAST, LineDirection.WEST);
}
position++;
}
//Only one child
else if (minPosition == maxPosition) {
linesPane = createLines(LineDirection.SOUTH, LineDirection.NORTH);
}
//Bridge between children
else {
if(drawHorizontal) {
if (upperCircleLineRepartition.contains(j)) {
linesPane = createLines(LineDirection.NORTH, LineDirection.EAST, LineDirection.WEST);
} else {
linesPane = createLines(LineDirection.WEST, LineDirection.EAST);
}
}else{
linesPane = createLines();
}
}
drawingZoneLayout.add(linesPane, j, i - 1);
}
}
circleLineRepartition = new ArrayList<>(upperCircleLineRepartition);
} catch (Exception e) {
System.out.println("Invalid line given");
}
}
}
drawingZoneLayout.setMaxSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
//TODO remove GridLines after debug
drawingZoneLayout.setGridLinesVisible(true);
this.getChildren().add(drawingZoneLayout);
}
private Pane createCircle(){
return createCircle(false,false);
}
private Pane createCircle(boolean isRoot, boolean isLeaf){
Pane circlePane = new Pane();
Circle circle = new Circle();
circle.centerXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
circle.centerYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
circle.radiusProperty().bind(Bindings.min(stage.widthProperty().divide(columnNumber).divide(2),stage.heightProperty().divide(rowNumber).divide(2)));
circlePane.getChildren().add(circle);
if(!isLeaf) {
circlePane.getChildren().add(createLines(LineDirection.SOUTH));
}
if(!isRoot){
circlePane.getChildren().add(createLines(LineDirection.NORTH));
}
return circlePane;
}
private Pane createLines(LineDirection ... directions){
Pane linesGroup = new Pane();
for(LineDirection direction : directions){
linesGroup.getChildren().add(createLine(direction));
}
return linesGroup;
}
private Line createLine(LineDirection direction){
Line line = new Line();
if(direction == LineDirection.EAST || direction == LineDirection.WEST){
line.startYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
line.endYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
line.startXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
if(direction == LineDirection.EAST){
line.endXProperty().bind(stage.widthProperty().divide(columnNumber));
}
else{
line.setEndX(0);
}
}
else{
line.startXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
line.endXProperty().bind(stage.widthProperty().divide(columnNumber).divide(2));
line.startYProperty().bind(stage.heightProperty().divide(rowNumber).divide(2));
if(direction == LineDirection.NORTH){
line.setEndY(0);
}else{
line.endYProperty().bind(stage.heightProperty().divide(rowNumber));
}
}
line.setStrokeWidth(1);
line.setFill(null);
line.setStroke(Color.BLACK);
return line;
}
private int getCenter(List<Integer> childrenNodesPosition) throws Exception {
if (childrenNodesPosition.size() == 0){
throw new Exception("Tried to get the center of an empty list");
}else{
int sum = 0;
for(int childNodePosition : childrenNodesPosition){
sum += childNodePosition;
}
return sum/childrenNodesPosition.size();
}
}
private List<Integer> getoddlyRepartedCenters(int nodeNumberPerParent, List<Integer> childrenNodesPosition) throws Exception {
int parentNumber = childrenNodesPosition.size()/nodeNumberPerParent;
int nextPosition = 0;
List<Integer> regularParentCenters = new ArrayList<>(parentNumber);
for(int i = 0 ; i < parentNumber ; i++){
regularParentCenters.add(getCenter(childrenNodesPosition.subList(nextPosition,nextPosition + nodeNumberPerParent)));
nextPosition = nextPosition + nodeNumberPerParent;
}
return regularParentCenters;
}
}
The result that I want to correct

why skia on windows has bad efficiency

I compared skia with gdi painting on windows. both drawing 98000 random lines. to my suprise that skia is far low efficiency than gdi(the skia painting cost 1600ms, while gdi cost 0ms). my testing code was paste below. any suggestions?
bool PaintCompare() {
//generate ramdon points
std::default_random_engine e(std::chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_real_distribution<float> u(10, 500);
SkPoint pts[100];
for (int i = 0; i<100; i++)
pts[i].set(u(e), u(e));
SkPaint paint;
paint.setColor(SkColorSetRGB(255, 0, 0));
//create skia canvas
sk_sp<SkSurface> rasterSurface(
SkSurface::MakeRasterN32Premul(600, 600));
SkCanvas* canvas = rasterSurface->getCanvas();
//draw lines with skia
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i<1000; i++)
{
for (int j = 1; j<99; j++)
{
canvas->drawLine(pts[j].fX, pts[j].fY, pts[j + 1].fX, pts[j + 1].fY, paint);
}
}
auto cost = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start);
sk_sp<SkImage> img(rasterSurface->makeImageSnapshot());
if (!img) { return false; }
SkBitmap skBmp;
if (!img->asLegacyBitmap(&skBmp, SkImage::kRO_LegacyBitmapMode)) {
return false;
}
//show bitmap on hdc
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = 600;
bmi.bmiHeader.biHeight = -600; // top-down image
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
HDC hdc = GetDC();
LPVOID pBits = NULL;
HBITMAP hBmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pBits, 0, 0);
skBmp.copyPixelsTo(pBits, skBmp.getSize());
CDC memdc;
memdc.CreateCompatibleDC(hdc);
memdc.SelectBitmap(hBmp);
BitBlt(hdc, 0, 0, 600, 600, memdc, 0, 0, SRCCOPY);
memdc.DeleteDC();
//draw with gdi
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
RECT rc{ 0,0,600,600 };
CBitmap bmp;
bmp.CreateCompatibleBitmap(hdc, 600, 600);
memdc.CreateCompatibleDC(hdc);
memdc.SelectBitmap(bmp);
memdc.FillSolidRect(&rc, RGB(0, 0, 0));
memdc.SelectPen(pen);
start = std::chrono::high_resolution_clock::now();
for (int i = 0; i<1000; i++)
{
for (int j = 1; j<99; j++)
{
memdc.MoveTo(pts[j].fX, pts[j].fY);
memdc.LineTo(pts[j + 1].fX, pts[j + 1].fY);
}
}
auto cost2 = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start);
//copy bitmap to window
BitBlt(hdc, 700, 0, 600, 600, memdc, 0, 0, SRCCOPY);
ReleaseDC(hdc);
memdc.DeleteDC();
//wchar_t buf[256];
//wsprintf(buf, L"left cost=%I64d, right cost=%I64d", cost.count(), cost2.count());
//GetParent().SetWindowText(buf);
//cost == 1596615 microseconds
//cost2 == 107253 microseconds
}
I found the problem finally. i give the result in debug mode!
in debug mode that skia with raster backend is 20 times slower than gdi.
however in release mode skia with raster backend is 4-5 times slower than gdi.
i had another test that skia uses opengl as backend. the result shows skia and gdi spend almost the same time. skia is about 15% slower than gdi.

Group an Array of Vectors according to certain Floors in Three.js

I have a list of Vectors which represent points on three different floors in three.js.
I am trying to group these vectors according to the floor they belong to. Is there a good formula to do this? Perhaps find height from on vector or something. Not sure how to go about this. Any help would be appreciated.
Thanks,
Rob
As Wilt said... Can't really help you without more info.
Still, if your floors are even and all stand on the xz plane (in my example), You may indeed check the points' height (position.y) against the floors'.
var container, renderer, scene, camera, controls;
var floors = [];
var points = [], materials = [], heights = [];
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.createElement('div');
document.body.appendChild(container);
container.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
// camera + controls
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 50, 750);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
//floors
for(i=0; i<3; i++) {
var planeGeometry = new THREE.BoxGeometry(500, 500, 10, 10);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff * Math.random(),
side: THREE.DoubleSide,
transparent: true,
opacity : 0.3,
depthWrite : false //get rid of coplanar glitches wall/floor
});
materials.push(planeMaterial);
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = Math.PI / 2;
//plane.rotation.y = Math.PI / 8; //Uncomment to see this doesn't work if the floors move, i.e. changing rotation/position. If this is what you need, just raycast from point to floor in the animation loop and count how many floors the ray goes through (intersects.length)
plane.position.y = 75*i;
heights.push(plane.position.y);
floors.push(plane);
scene.add(plane);
}
//wall
var height = heights[2];
var planeGeometry = new THREE.BoxGeometry(500, height+100, 10, 10);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff * Math.random(),
side: THREE.DoubleSide,
transparent: true,
opacity:0.3,
depthWrite : false //get rid of coplanar glitches wall/floor
});
materials.push(planeMaterial);
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.y = heights[1]+45;
plane.position.z = -510/2;
scene.add(plane);
// points
for (i=0; i<200; i++) {
var sphereGeometry = new THREE.SphereGeometry(3, 32, 16);
var sphere = new THREE.Mesh(sphereGeometry);
sphere.position.x = Math.random() * 500 - 250;
sphere.position.y = Math.random() * 300 - 100;
sphere.position.z = Math.random() * 500 - 250;
scene.add(sphere);
points.push(sphere);
}
// events
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize(event) {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function addSpheres() {
//addSpheres
for (i=0;i<200;i++) {
var that = points[i].position.y;
points[i].position.y = ( that < heights[0] ) ? 200 : that - 0.5;
if ( that > heights[0] && that < heights[1] ) points[i].material = materials[0];
if ( that < heights[2] && that > heights[1] ) points[i].material = materials[1];
if ( that > heights[2] ) points[i].material = materials[2];
points[i].material.needsUpdate = true;
}
}
function animate() {
controls.update();
addSpheres();
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
Now, feel free to "group" these points according to your needs.
Please note that "vectors" are different from "points". Read more about the difference.
Raycasting would be the way to go if you had a more complex scene (moving floors/different planes, points moving in different directions).

Apply texture to grid

I would like to apply a texture to a grid in 3d space using Processing, I've tried declaring a PImage and setting the .jpg file with loadimage with no results..
PImage tex;
void setup() {
size(800, 600, P3D);
tex=loadImage("ground104");
noCursor();
}
void draw()
{
directionalLight(255, 255, 255, 0, 0, -1);
background(180);
drawPlane();
}
void drawPlane()
{ //lights();
int s = 10000;
int ss = 500;
fill(0, 200, 20); stroke(200); for(int i = 0; i < s; i += ss) {
stroke(0,100,0);
strokeWeight(3);
beginShape(QUAD_STRIP);
for(int j = 0; j <= s; j += ss)
{
texture(tex);
vertex(j, i, 0);
vertex(j, i + ss, 0);
}
endShape(); } noStroke(); }
Do you have any advice?
Thanks!
looks like you need a file extension like .jpg. You can troubleshoot by running the code from the reference page:
http://www.processing.org/reference/texture_
size(100, 100, P3D);
noStroke();
PImage img = loadImage("laDefense.jpg");
beginShape();
texture(img);
vertex(10, 20, 0, 0);
vertex(80, 5, 100, 0);
vertex(95, 90, 100, 100);
vertex(40, 95, 0, 100);
endShape();
and replace laDefense.jpg with your image name. Also, it needs to be placed in the data directory in the sketch directory. If it works, then your problem is elsewhere. I am not sure what your plan is in the sketch, but you might find peasycam useful for troubleshooting in 3d.
http://mrfeinberg.com/peasycam/
another technique is to increment a float by 0.01 per frame and call a RotateX(), Y or Z or all of the above at the beginning of your draw() method / loop.
Thank you for your reply!
I've changed my code to this and now you can run it and see what I get (first download the grass.jpg from https://www.dropbox.com/s/fsda0tih67q8tll/grass.jpg?m). I'm close but I wonder why the grid is green when it was supposed to be a grass land...
PImage tex;
void setup()
{
size(800, 600, P3D);
tex=loadImage("grass.jpg");
noCursor();
}
void draw()
{
translate(width/2 , height/2 , 0); // center of screen
rotateX(QUARTER_PI * 1.0); // move camera up
rotateZ(QUARTER_PI * 1.8);
//rotateZ(camZ.val + offset); // rotate around turret
rotateZ(map(mouseX, mouseY, width, 2.5, -2.5));
translate(-1000, 0, -1000);
directionalLight(255, 255, 255, 0, 0, -1);
background(180);
drawPlane();
}
void drawPlane()
{ //lights();
int s = 10000;
int ss = 500;
fill(0, 200, 20); stroke(200); for(int i = 0; i < s; i += ss) {
stroke(0,100,0);
strokeWeight(3);
beginShape(QUAD_STRIP);
for(int j = 0; j <= s; j += ss)
{
texture(tex);
vertex(j, i, 0);
vertex(j, i + ss, 0);
}
endShape();
}
noStroke();
}

Resources