How to create a 3d / surface chart with JavaFX? -


problem

i tried create 3d chart javafx seems more difficult 1 expect.

my current way of doing create trianglemesh, that's rather circumstantial. i'd provide list<point3d> chart , chart should rendered surface.

however, simple pyramid 5 data points turns out rather complicated:

    float h = 200;                    // height     float s = 200;                    // side      trianglemesh pyramidmesh = new trianglemesh();      pyramidmesh.gettexcoords().addall(0,0);     pyramidmesh.getpoints().addall(             0,    0,    0,            // point 0 - top             0,    h,    -s/2,         // point 1 - front             -s/2, h,    0,            // point 2 - left             s/2,  h,    0,            // point 3 -             0,    h,    s/2           // point 4 - right         );      pyramidmesh.getfaces().addall(       0,0,  2,0,  1,0,          // front left face       0,0,  1,0,  3,0,          // front right face       0,0,  3,0,  4,0,          // right face       0,0,  4,0,  2,0,          // left face       4,0,  1,0,  2,0,          // bottom rear face       4,0,  3,0,  1,0           // bottom front face   );  

questions

  • does know how create 3d chart javafx?
  • is trianglemesh proper way it?
  • how convert list<point3d> trianglemesh?

code

import javafx.animation.timeline; import javafx.application.application; import javafx.event.eventhandler; import javafx.scene.group; import javafx.scene.node; import javafx.scene.perspectivecamera; import javafx.scene.scene; import javafx.scene.input.keyevent; import javafx.scene.input.mouseevent; import javafx.scene.paint.color; import javafx.scene.paint.phongmaterial; import javafx.scene.shape.box; import javafx.scene.shape.drawmode; import javafx.scene.shape.meshview; import javafx.scene.shape.trianglemesh; import javafx.scene.transform.rotate; import javafx.scene.transform.scale; import javafx.scene.transform.translate; import javafx.stage.stage; import javafx.util.duration;  public class chart3dsampleapp extends application {      final group root = new group();     final group axisgroup = new group();     final xform world = new xform();     final perspectivecamera camera = new perspectivecamera(true);     final xform cameraxform = new xform();     final xform cameraxform2 = new xform();     final xform cameraxform3 = new xform();     final double cameradistance = 1450;     final xform moleculegroup = new xform();     private timeline timeline;     boolean timelineplaying = false;     double one_frame = 1.0 / 24.0;     double delta_multiplier = 200.0;     double control_multiplier = 10.1;     double shift_multiplier = 0.1;     double alt_multiplier = 0.5;     double mouseposx;     double mouseposy;     double mouseoldx;     double mouseoldy;     double mousedeltax;     double mousedeltay;      private void buildscene() {         root.getchildren().add(world);     }      private void buildcamera() {         root.getchildren().add(cameraxform);         cameraxform.getchildren().add(cameraxform2);         cameraxform2.getchildren().add(cameraxform3);         cameraxform3.getchildren().add(camera);         cameraxform3.setrotatez(0);          camera.setnearclip(0.1);         camera.setfarclip(10000.0);         camera.settranslatez(-cameradistance);         cameraxform.ry.setangle(0);         cameraxform.rx.setangle(0);     }      private void buildaxes() {         final phongmaterial redmaterial = new phongmaterial();         redmaterial.setdiffusecolor(color.darkred);         redmaterial.setspecularcolor(color.red);          final phongmaterial greenmaterial = new phongmaterial();         greenmaterial.setdiffusecolor(color.darkgreen);         greenmaterial.setspecularcolor(color.green);          final phongmaterial bluematerial = new phongmaterial();         bluematerial.setdiffusecolor(color.darkblue);         bluematerial.setspecularcolor(color.blue);          final box xaxis = new box(300, 1, 300);         final box yaxis = new box(1, 300, 300);         final box zaxis = new box(300, 300, 1);          yaxis.settranslatey(-150);         yaxis.settranslatex(150);         zaxis.settranslatey(-150);         zaxis.settranslatez(150);          xaxis.setmaterial(redmaterial);         yaxis.setmaterial(greenmaterial);         zaxis.setmaterial(bluematerial);          axisgroup.getchildren().addall(xaxis, yaxis, zaxis);         world.getchildren().addall(axisgroup);     }      private void buildchart() {        final phongmaterial whitematerial = new phongmaterial();       whitematerial.setdiffusecolor(color.white);       whitematerial.setspecularcolor(color.lightblue);          float h = 200;                    // height         float s = 200;                    // side          trianglemesh pyramidmesh = new trianglemesh();          pyramidmesh.gettexcoords().addall(0,0);         pyramidmesh.getpoints().addall(                 0,    0,    0,            // point 0 - top                 0,    h,    -s/2,         // point 1 - front                 -s/2, h,    0,            // point 2 - left                 s/2,  h,    0,            // point 3 -                 0,    h,    s/2           // point 4 - right             );          pyramidmesh.getfaces().addall(           0,0,  2,0,  1,0,          // front left face           0,0,  1,0,  3,0,          // front right face           0,0,  3,0,  4,0,          // right face           0,0,  4,0,  2,0,          // left face           4,0,  1,0,  2,0,          // bottom rear face           4,0,  3,0,  1,0           // bottom front face       );            meshview pyramid = new meshview(pyramidmesh);         pyramid.setdrawmode(drawmode.fill);         pyramid.setmaterial(whitematerial);         pyramid.settranslatey(-h);          world.getchildren().addall(pyramid);     }       private void handlemouse(scene scene, final node root) {         scene.setonmousepressed(new eventhandler<mouseevent>() {             @override public void handle(mouseevent me) {                 mouseposx = me.getscenex();                 mouseposy = me.getsceney();                 mouseoldx = me.getscenex();                 mouseoldy = me.getsceney();             }         });         scene.setonmousedragged(new eventhandler<mouseevent>() {             @override             public void handle(mouseevent me) {                 mouseoldx = mouseposx;                 mouseoldy = mouseposy;                 mouseposx = me.getscenex();                 mouseposy = me.getsceney();                 mousedeltax = (mouseposx - mouseoldx);                 mousedeltay = (mouseposy - mouseoldy);                  double modifier = 1.0;                 double modifierfactor = 0.1;                  if (me.iscontroldown()) {                     modifier = 0.1;                 }                 if (me.isshiftdown()) {                     modifier = 10.0;                 }                 if (me.isprimarybuttondown()) {                     cameraxform.ry.setangle(cameraxform.ry.getangle() - mousedeltax * modifierfactor * modifier * 2.0);  // +                     cameraxform.rx.setangle(cameraxform.rx.getangle() + mousedeltay * modifierfactor * modifier * 2.0);  // -                 } else if (me.issecondarybuttondown()) {                     double z = camera.gettranslatez();                     double newz = z + mousedeltax * modifierfactor * modifier;                     camera.settranslatez(newz);                 } else if (me.ismiddlebuttondown()) {                     cameraxform2.t.setx(cameraxform2.t.getx() + mousedeltax * modifierfactor * modifier * 0.3);  // -                     cameraxform2.t.sety(cameraxform2.t.gety() + mousedeltay * modifierfactor * modifier * 0.3);  // -                 }             }         });     }      private void handlekeyboard(scene scene, final node root) {         final boolean movecamera = true;         scene.setonkeypressed(new eventhandler<keyevent>() {             @override             public void handle(keyevent event) {                 duration currenttime;                 switch (event.getcode()) {                     case z:                         if (event.isshiftdown()) {                             cameraxform.ry.setangle(0.0);                             cameraxform.rx.setangle(0.0);                             camera.settranslatez(-300.0);                         }                         cameraxform2.t.setx(0.0);                         cameraxform2.t.sety(0.0);                         break;                     case x:                         if (event.iscontroldown()) {                             if (axisgroup.isvisible()) {                                 axisgroup.setvisible(false);                             } else {                                 axisgroup.setvisible(true);                             }                         }                         break;                     case s:                         if (event.iscontroldown()) {                             if (moleculegroup.isvisible()) {                                 moleculegroup.setvisible(false);                             } else {                                 moleculegroup.setvisible(true);                             }                         }                         break;                     case space:                         if (timelineplaying) {                             timeline.pause();                             timelineplaying = false;                         } else {                             timeline.play();                             timelineplaying = true;                         }                         break;                     case up:                         if (event.iscontroldown() && event.isshiftdown()) {                             cameraxform2.t.sety(cameraxform2.t.gety() - 10.0 * control_multiplier);                         } else if (event.isaltdown() && event.isshiftdown()) {                             cameraxform.rx.setangle(cameraxform.rx.getangle() - 10.0 * alt_multiplier);                         } else if (event.iscontroldown()) {                             cameraxform2.t.sety(cameraxform2.t.gety() - 1.0 * control_multiplier);                         } else if (event.isaltdown()) {                             cameraxform.rx.setangle(cameraxform.rx.getangle() - 2.0 * alt_multiplier);                         } else if (event.isshiftdown()) {                             double z = camera.gettranslatez();                             double newz = z + 5.0 * shift_multiplier;                             camera.settranslatez(newz);                         }                         break;                     case down:                         if (event.iscontroldown() && event.isshiftdown()) {                             cameraxform2.t.sety(cameraxform2.t.gety() + 10.0 * control_multiplier);                         } else if (event.isaltdown() && event.isshiftdown()) {                             cameraxform.rx.setangle(cameraxform.rx.getangle() + 10.0 * alt_multiplier);                         } else if (event.iscontroldown()) {                             cameraxform2.t.sety(cameraxform2.t.gety() + 1.0 * control_multiplier);                         } else if (event.isaltdown()) {                             cameraxform.rx.setangle(cameraxform.rx.getangle() + 2.0 * alt_multiplier);                         } else if (event.isshiftdown()) {                             double z = camera.gettranslatez();                             double newz = z - 5.0 * shift_multiplier;                             camera.settranslatez(newz);                         }                         break;                     case right:                         if (event.iscontroldown() && event.isshiftdown()) {                             cameraxform2.t.setx(cameraxform2.t.getx() + 10.0 * control_multiplier);                         } else if (event.isaltdown() && event.isshiftdown()) {                             cameraxform.ry.setangle(cameraxform.ry.getangle() - 10.0 * alt_multiplier);                         } else if (event.iscontroldown()) {                             cameraxform2.t.setx(cameraxform2.t.getx() + 1.0 * control_multiplier);                         } else if (event.isaltdown()) {                             cameraxform.ry.setangle(cameraxform.ry.getangle() - 2.0 * alt_multiplier);                         }                         break;                     case left:                         if (event.iscontroldown() && event.isshiftdown()) {                             cameraxform2.t.setx(cameraxform2.t.getx() - 10.0 * control_multiplier);                         } else if (event.isaltdown() && event.isshiftdown()) {                             cameraxform.ry.setangle(cameraxform.ry.getangle() + 10.0 * alt_multiplier);  // -                         } else if (event.iscontroldown()) {                             cameraxform2.t.setx(cameraxform2.t.getx() - 1.0 * control_multiplier);                         } else if (event.isaltdown()) {                             cameraxform.ry.setangle(cameraxform.ry.getangle() + 2.0 * alt_multiplier);  // -                         }                         break;                 }             }         });     }          @override     public void start(stage primarystage) {         buildscene();         buildcamera();         buildaxes();         buildchart();          scene scene = new scene(root, 1600, 900, true);         scene.setfill(color.grey);         handlekeyboard(scene, world);         handlemouse(scene, world);          primarystage.setscene(scene);         primarystage.show();          scene.setcamera(camera);      }      /**      * main() method ignored in correctly deployed javafx application.      * main() serves fallback in case application can not      * launched through deployment artifacts, e.g., in ides limited fx      * support. netbeans ignores main().      *      * @param args command line arguments      */     public static void main(string[] args) {         system.setproperty("prism.dirtyopts", "false");         launch(args);     }      public static class xform extends group {        public enum rotateorder {           xyz, xzy, yxz, yzx, zxy, zyx       }        public translate t  = new translate();        public translate p  = new translate();        public translate ip = new translate();        public rotate rx = new rotate();       { rx.setaxis(rotate.x_axis); }       public rotate ry = new rotate();       { ry.setaxis(rotate.y_axis); }       public rotate rz = new rotate();       { rz.setaxis(rotate.z_axis); }       public scale s = new scale();        public xform() {            super();            gettransforms().addall(t, rz, ry, rx, s);        }        public xform(rotateorder rotateorder) {            super();            // choose order of rotations based on rotateorder           switch (rotateorder) {           case xyz:               gettransforms().addall(t, p, rz, ry, rx, s, ip);                break;           case xzy:               gettransforms().addall(t, p, ry, rz, rx, s, ip);                break;           case yxz:               gettransforms().addall(t, p, rz, rx, ry, s, ip);                break;           case yzx:               gettransforms().addall(t, p, rx, rz, ry, s, ip);  // camera               break;           case zxy:               gettransforms().addall(t, p, ry, rx, rz, s, ip);                break;           case zyx:               gettransforms().addall(t, p, rx, ry, rz, s, ip);                break;           }       }        public void settranslate(double x, double y, double z) {           t.setx(x);           t.sety(y);           t.setz(z);       }        public void settranslate(double x, double y) {           t.setx(x);           t.sety(y);       }        // cannot override these methods final:       // public void settranslatex(double x) { t.setx(x); }       // public void settranslatey(double y) { t.sety(y); }       // public void settranslatez(double z) { t.setz(z); }       // use these methods instead:       public void settx(double x) { t.setx(x); }       public void setty(double y) { t.sety(y); }       public void settz(double z) { t.setz(z); }        public void setrotate(double x, double y, double z) {           rx.setangle(x);           ry.setangle(y);           rz.setangle(z);       }        public void setrotatex(double x) { rx.setangle(x); }       public void setrotatey(double y) { ry.setangle(y); }       public void setrotatez(double z) { rz.setangle(z); }       public void setrx(double x) { rx.setangle(x); }       public void setry(double y) { ry.setangle(y); }       public void setrz(double z) { rz.setangle(z); }        public void setscale(double scalefactor) {           s.setx(scalefactor);           s.sety(scalefactor);           s.setz(scalefactor);       }        public void setscale(double x, double y, double z) {           s.setx(x);           s.sety(y);           s.setz(z);       }        // cannot override these methods final:       // public void setscalex(double x) { s.setx(x); }       // public void setscaley(double y) { s.sety(y); }       // public void setscalez(double z) { s.setz(z); }       // use these methods instead:       public void setsx(double x) { s.setx(x); }       public void setsy(double y) { s.sety(y); }       public void setsz(double z) { s.setz(z); }        public void setpivot(double x, double y, double z) {           p.setx(x);           p.sety(y);           p.setz(z);           ip.setx(-x);           ip.sety(-y);           ip.setz(-z);       }        public void reset() {           t.setx(0.0);           t.sety(0.0);           t.setz(0.0);           rx.setangle(0.0);           ry.setangle(0.0);           rz.setangle(0.0);           s.setx(1.0);           s.sety(1.0);           s.setz(1.0);           p.setx(0.0);           p.sety(0.0);           p.setz(0.0);           ip.setx(0.0);           ip.sety(0.0);           ip.setz(0.0);       }        public void resettsp() {           t.setx(0.0);           t.sety(0.0);           t.setz(0.0);           s.setx(1.0);           s.sety(1.0);           s.setz(1.0);           p.setx(0.0);           p.sety(0.0);           p.setz(0.0);           ip.setx(0.0);           ip.sety(0.0);           ip.setz(0.0);       }   }  } 

the chart should e. g. this:

enter image description here

or this:

enter image description here

in end should possible display e. g. the result of perlin noise, instead of perlin noise value being color value, it's height value.

thank help!

thanks nwdx's answer managed create useful. it's not complete chart application , hope more know how can provide better answer, i'll post result nontheless.

you can use mouse dragging rotation , mouse wheel zooming. example shows perlin noise graph diffuse map used on mesh.

the core isn't code. it's turning 2d-array mesh:

    // perlin noise     float[][] noisearray = createnoise( size);      // mesh     trianglemesh mesh = new trianglemesh();      // create points x/z     float amplification = 100; // amplification of noise      (int x = 0; x < size; x++) {         (int z = 0; z < size; z++) {             mesh.getpoints().addall(x, noisearray[x][z] * amplification, z);         }     }      // texture     int length = size;     float total = length;      (float x = 0; x < length - 1; x++) {         (float y = 0; y < length - 1; y++) {              float x0 = x / total;             float y0 = y / total;             float x1 = (x + 1) / total;             float y1 = (y + 1) / total;              mesh.gettexcoords().addall( //                     x0, y0, // 0, top-left                     x0, y1, // 1, bottom-left                     x1, y1, // 2, top-right                     x1, y1 // 3, bottom-right             );           }     }      // faces     (int x = 0; x < length - 1; x++) {         (int z = 0; z < length - 1; z++) {              int tl = x * length + z; // top-left             int bl = x * length + z + 1; // bottom-left             int tr = (x + 1) * length + z; // top-right             int br = (x + 1) * length + z + 1; // bottom-right              int offset = (x * (length - 1) + z ) * 8 / 2; // div 2 because have u , v in list              // working             mesh.getfaces().addall(bl, offset + 1, tl, offset + 0, tr, offset + 2);             mesh.getfaces().addall(tr, offset + 2, br, offset + 3, bl, offset + 1);          }     } 

if has better algorithm, please share it. don't mind if reuse code.

the full working example:

import java.util.arraylist; import java.util.list;  import javafx.application.application; import javafx.event.eventhandler; import javafx.geometry.point3d; import javafx.scene.depthtest; import javafx.scene.group; import javafx.scene.perspectivecamera; import javafx.scene.scene; import javafx.scene.sceneantialiasing; import javafx.scene.canvas.canvas; import javafx.scene.image.image; import javafx.scene.image.imageview; import javafx.scene.image.pixelwriter; import javafx.scene.image.writableimage; import javafx.scene.input.scrollevent; import javafx.scene.layout.pane; import javafx.scene.layout.stackpane; import javafx.scene.paint.color; import javafx.scene.paint.cyclemethod; import javafx.scene.paint.lineargradient; import javafx.scene.paint.paint; import javafx.scene.paint.phongmaterial; import javafx.scene.paint.stop; import javafx.scene.shape.cullface; import javafx.scene.shape.drawmode; import javafx.scene.shape.line; import javafx.scene.shape.meshview; import javafx.scene.shape.rectangle; import javafx.scene.shape.trianglemesh; import javafx.scene.transform.rotate; import javafx.stage.stage;  public class chart3ddemo extends application {      // size of graph     int size = 400;      // variables mouse interaction     private double mouseposx, mouseposy;     private double mouseoldx, mouseoldy;     private final rotate rotatex = new rotate(20, rotate.x_axis);     private final rotate rotatey = new rotate(-45, rotate.y_axis);      @override     public void start(stage primarystage) {          // create axis walls         group cube = createcube(size);          // initial cube rotation         cube.gettransforms().addall(rotatex, rotatey);          // add objects scene         stackpane root = new stackpane();         root.getchildren().add(cube);          // perlin noise         float[][] noisearray = createnoise( size);          // mesh         trianglemesh mesh = new trianglemesh();          // create points x/z         float amplification = 100; // amplification of noise          (int x = 0; x < size; x++) {             (int z = 0; z < size; z++) {                 mesh.getpoints().addall(x, noisearray[x][z] * amplification, z);             }         }          // texture         int length = size;         float total = length;          (float x = 0; x < length - 1; x++) {             (float y = 0; y < length - 1; y++) {                  float x0 = x / total;                 float y0 = y / total;                 float x1 = (x + 1) / total;                 float y1 = (y + 1) / total;                  mesh.gettexcoords().addall( //                         x0, y0, // 0, top-left                         x0, y1, // 1, bottom-left                         x1, y1, // 2, top-right                         x1, y1 // 3, bottom-right                 );               }         }          // faces         (int x = 0; x < length - 1; x++) {             (int z = 0; z < length - 1; z++) {                  int tl = x * length + z; // top-left                 int bl = x * length + z + 1; // bottom-left                 int tr = (x + 1) * length + z; // top-right                 int br = (x + 1) * length + z + 1; // bottom-right                  int offset = (x * (length - 1) + z ) * 8 / 2; // div 2 because have u , v in list                  // working                 mesh.getfaces().addall(bl, offset + 1, tl, offset + 0, tr, offset + 2);                 mesh.getfaces().addall(tr, offset + 2, br, offset + 3, bl, offset + 1);              }         }           // material         image diffusemap = createimage(size, noisearray);          phongmaterial material = new phongmaterial();         material.setdiffusemap(diffusemap);         material.setspecularcolor(color.white);          // mesh view         meshview meshview = new meshview(mesh);         meshview.settranslatex(-0.5 * size);         meshview.settranslatez(-0.5 * size);         meshview.setmaterial(material);         meshview.setcullface(cullface.none);         meshview.setdrawmode(drawmode.fill);         meshview.setdepthtest(depthtest.enable);          cube.getchildren().addall(meshview);          // testing / debugging stuff: show diffuse map on chart         imageview iv = new imageview(diffusemap);         iv.settranslatex(-0.5 * size);         iv.settranslatey(-0.10 * size);         iv.setrotate(90);         iv.setrotationaxis(new point3d(1, 0, 0));         cube.getchildren().add(iv);          // scene         scene scene = new scene(root, 1600, 900, true, sceneantialiasing.balanced);         scene.setcamera(new perspectivecamera());          scene.setonmousepressed(me -> {             mouseoldx = me.getscenex();             mouseoldy = me.getsceney();         });         scene.setonmousedragged(me -> {             mouseposx = me.getscenex();             mouseposy = me.getsceney();             rotatex.setangle(rotatex.getangle() - (mouseposy - mouseoldy));             rotatey.setangle(rotatey.getangle() + (mouseposx - mouseoldx));             mouseoldx = mouseposx;             mouseoldy = mouseposy;          });          makezoomable(root);          primarystage.setresizable(false);         primarystage.setscene(scene);         primarystage.show();       }      /**      * create texture uv mapping      * @param size      * @param noise      * @return      */     public image createimage(double size, float[][] noise) {          int width = (int) size;         int height = (int) size;          writableimage wr = new writableimage(width, height);         pixelwriter pw = wr.getpixelwriter();         (int x = 0; x < width; x++) {             (int y = 0; y < height; y++) {                  float value = noise[x][y];                  double gray = normalizevalue(value, -.5, .5, 0., 1.);                  gray = clamp(gray, 0, 1);                  color color = color.red.interpolate(color.yellow, gray);                  pw.setcolor(x, y, color);              }         }          return wr;      }      /**      * axis wall      */     public static class axis extends pane {          rectangle wall;          public axis(double size) {              // wall             // first wall, lines => overlapping of lines on walls             // works             wall = new rectangle(size, size);             getchildren().add(wall);              // grid             double ztranslate = 0;             double linewidth = 1.0;             color gridcolor = color.white;              (int y = 0; y <= size; y += size / 10) {                  line line = new line(0, 0, size, 0);                 line.setstroke(gridcolor);                 line.setfill(gridcolor);                 line.settranslatey(y);                 line.settranslatez(ztranslate);                 line.setstrokewidth(linewidth);                  getchildren().addall(line);              }              (int x = 0; x <= size; x += size / 10) {                  line line = new line(0, 0, 0, size);                 line.setstroke(gridcolor);                 line.setfill(gridcolor);                 line.settranslatex(x);                 line.settranslatez(ztranslate);                 line.setstrokewidth(linewidth);                  getchildren().addall(line);              }              // labels             // todo: reason text makes wall have offset             // for( int y=0; y <= size; y+=size/10) {             //             // text text = new text( ""+y);             // text.settranslatex(size + 10);             //             // text.settranslatey(y);             // text.settranslatez(ztranslate);             //             // getchildren().addall(text);             //             // }          }          public void setfill(paint paint) {             wall.setfill(paint);         }      }      public void makezoomable(stackpane control) {          final double max_scale = 20.0;         final double min_scale = 0.1;          control.addeventfilter(scrollevent.any, new eventhandler<scrollevent>() {              @override             public void handle(scrollevent event) {                  double delta = 1.2;                  double scale = control.getscalex();                  if (event.getdeltay() < 0) {                     scale /= delta;                 } else {                     scale *= delta;                 }                  scale = clamp(scale, min_scale, max_scale);                  control.setscalex(scale);                 control.setscaley(scale);                  event.consume();              }          });      }      /**      * create axis walls      * @param size      * @return      */     private group createcube(int size) {          group cube = new group();          // size of cube         color color = color.darkcyan;          list<axis> cubefaces = new arraylist<>();         axis r;          // face         r = new axis(size);         r.setfill(color.derivecolor(0.0, 1.0, (1 - 0.5 * 1), 1.0));         r.settranslatex(-0.5 * size);         r.settranslatey(-0.5 * size);         r.settranslatez(0.5 * size);          cubefaces.add(r);          // bottom face         r = new axis(size);         r.setfill(color.derivecolor(0.0, 1.0, (1 - 0.4 * 1), 1.0));         r.settranslatex(-0.5 * size);         r.settranslatey(0);         r.setrotationaxis(rotate.x_axis);         r.setrotate(90);          cubefaces.add(r);          // right face         r = new axis(size);         r.setfill(color.derivecolor(0.0, 1.0, (1 - 0.3 * 1), 1.0));         r.settranslatex(-1 * size);         r.settranslatey(-0.5 * size);         r.setrotationaxis(rotate.y_axis);         r.setrotate(90);          // cubefaces.add( r);          // left face         r = new axis(size);         r.setfill(color.derivecolor(0.0, 1.0, (1 - 0.2 * 1), 1.0));         r.settranslatex(0);         r.settranslatey(-0.5 * size);         r.setrotationaxis(rotate.y_axis);         r.setrotate(90);          cubefaces.add(r);          // top face         r = new axis(size);         r.setfill(color.derivecolor(0.0, 1.0, (1 - 0.1 * 1), 1.0));         r.settranslatex(-0.5 * size);         r.settranslatey(-1 * size);         r.setrotationaxis(rotate.x_axis);         r.setrotate(90);          // cubefaces.add( r);          // front face         r = new axis(size);         r.setfill(color.derivecolor(0.0, 1.0, (1 - 0.1 * 1), 1.0));         r.settranslatex(-0.5 * size);         r.settranslatey(-0.5 * size);         r.settranslatez(-0.5 * size);          // cubefaces.add( r);          cube.getchildren().addall(cubefaces);          return cube;     }      /**      * create array of given size values of perlin noise      * @param size      * @return      */     private float[][] createnoise( int size) {         float[][] noisearray = new float[(int) size][(int) size];          (int x = 0; x < size; x++) {             (int y = 0; y < size; y++) {                  double frequency = 10.0 / (double) size;                  double noise = improvednoise.noise(x * frequency, y * frequency, 0);                  noisearray[x][y] = (float) noise;             }         }          return noisearray;      }      public static double normalizevalue(double value, double min, double max, double newmin, double newmax) {          return (value - min) * (newmax - newmin) / (max - min) + newmin;      }      public static double clamp(double value, double min, double max) {          if (double.compare(value, min) < 0)             return min;          if (double.compare(value, max) > 0)             return max;          return value;     }          /**      * perlin noise generator      *       * // java reference implementation of improved noise - copyright 2002 ken perlin.      * // http://mrl.nyu.edu/~perlin/paper445.pdf      * // http://mrl.nyu.edu/~perlin/noise/      */     public final static class improvednoise {     static public double noise(double x, double y, double z) {        int x = (int)math.floor(x) & 255,                  // find unit cube            y = (int)math.floor(y) & 255,                  // contains point.            z = (int)math.floor(z) & 255;        x -= math.floor(x);                                // find relative x,y,z        y -= math.floor(y);                                // of point in cube.        z -= math.floor(z);        double u = fade(x),                                // compute fade curves               v = fade(y),                                // each of x,y,z.               w = fade(z);        int = p[x  ]+y, aa = p[a]+z, ab = p[a+1]+z,      // hash coordinates of            b = p[x+1]+y, ba = p[b]+z, bb = p[b+1]+z;      // 8 cube corners,         return lerp(w, lerp(v, lerp(u, grad(p[aa  ], x  , y  , z   ),  // , add                                       grad(p[ba  ], x-1, y  , z   )), // blended                               lerp(u, grad(p[ab  ], x  , y-1, z   ),  // results                                       grad(p[bb  ], x-1, y-1, z   ))),//  8                       lerp(v, lerp(u, grad(p[aa+1], x  , y  , z-1 ),  // corners                                       grad(p[ba+1], x-1, y  , z-1 )), // of cube                               lerp(u, grad(p[ab+1], x  , y-1, z-1 ),                                       grad(p[bb+1], x-1, y-1, z-1 ))));     }     static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); }     static double lerp(double t, double a, double b) { return + t * (b - a); }     static double grad(int hash, double x, double y, double z) {        int h = hash & 15;                      // convert lo 4 bits of hash code        double u = h<8 ? x : y,                 // 12 gradient directions.               v = h<4 ? y : h==12||h==14 ? x : z;        return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);     }     static final int p[] = new int[512], permutation[] = { 151,160,137,91,90,15,     131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,     190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,     88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,     77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,     102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,     135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,     5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,     223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,     129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,     251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,     49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,     138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180     };     static { (int i=0; < 256 ; i++) p[256+i] = p[i] = permutation[i]; }     }      public static void main(string[] args) {         launch(args);     }   } 

screenshot:

enter image description here


Comments

Popular posts from this blog

python - No exponential form of the z-axis in matplotlib-3D-plots -

php - Best Light server (Linux + Web server + Database) for Raspberry Pi -

c# - "Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types" error when deserializing class -