Iam working on a triangle mesh for which i need to color each vertext with a specific color. I followed the example provided here
Using texture for triangle mesh without having to read/write an image file
which helped a lot, but i am stuck with tecturing the vertices, the example above describes coloring each vertex by creating a palette from numColors, I tried the same for my set of specific colors array i have, the palette is created but the vertices are not colored in the order that i wanted to, Any example on this would really help, how to color each vertex in a triangle mesh with a provided specific set of colors (for each vertex) by cerating a color palette.
Thanks
Here is my example
import java.io.File;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.DrawMode;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.TriangleMesh;
import javafx.scene.shape.VertexFormat;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
public class Sample1 extends Application {
private static final double MODEL_SCALE_FACTOR = 10;
private static final double MODEL_X_OFFSET = 0; // standard
private static final double MODEL_Y_OFFSET = 0; // standard
private static int VIEWPORT_SIZE = 800;
private double mouseOldX, mouseOldY = 0;
private Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
private Rotate rotateZ = new Rotate(0, Rotate.Z_AXIS);
private Group root = new Group();
//Xform sceneRoot;
PerspectiveCamera camera;
private TriangleMesh mesh;
// Color[] colorArray;
#Override
public void start(Stage primaryStage) {
camera = new PerspectiveCamera(false);
camera.setTranslateX(0);
camera.setTranslateY(0);
camera.setTranslateZ(0);
camera.setNearClip(0.1);
camera.setFarClip(1000.0);
camera.getTransforms().addAll(rotateX, rotateY, new Translate(0, 0, 0));
root.setRotationAxis(Rotate.Y_AXIS);
root.setRotate(200);
rotateX.setPivotX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
rotateX.setPivotY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
rotateX.setPivotZ(VIEWPORT_SIZE / 2);
rotateY.setPivotX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
rotateY.setPivotY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
rotateY.setPivotZ(VIEWPORT_SIZE / 2);
rotateZ.setPivotX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
rotateZ.setPivotY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
rotateZ.setPivotZ(VIEWPORT_SIZE / 2);
root.setScaleX(MODEL_SCALE_FACTOR);
root.setScaleY(MODEL_SCALE_FACTOR);
root.setScaleZ(MODEL_SCALE_FACTOR);
createModel();
Scene scene = new Scene(root, 800, 500);
scene.setFill(Color.rgb(10, 10, 40));
scene.setCamera(camera);
scene.setOnScroll(new EventHandler<ScrollEvent>() {
#Override
public void handle(ScrollEvent event) {
double zoomFactor = 1.05;
double deltaY = event.getDeltaY();
if (deltaY < 0) {
zoomFactor = 2.0 - zoomFactor;
}
// System.out.println(zoomFactor);
root.setScaleX(root.getScaleX() * zoomFactor);
root.setScaleY(root.getScaleY() * zoomFactor);
root.setScaleZ(root.getScaleZ() * zoomFactor);
event.consume();
}
});
scene.setOnMousePressed(event -> {
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
scene.setOnMouseDragged(event -> {
rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
primaryStage.setTitle("Sample Mesh");
primaryStage.setScene(scene);
primaryStage.centerOnScreen();
primaryStage.show();
}
private void createModel() {
mesh = new TriangleMesh(VertexFormat.POINT_NORMAL_TEXCOORD);
addPoints();
addFaces();
addNormals();
PhongMaterial mat = new PhongMaterial();
mat.setDiffuseMap(colorPalette(colorArray));
int numVertices = mesh.getPoints().size() / 3;
int numColors = colorArray.length;
IntStream.range(0, numVertices).boxed()
.forEach(i -> mesh.getTexCoords()
.addAll(getTextureLocation(i * numColors / numVertices, numColors)));
MeshView meshView = new MeshView(mesh);
meshView.setMaterial(mat);
meshView.setDrawMode(DrawMode.FILL);
meshView.setTranslateX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
meshView.setTranslateY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
meshView.setTranslateZ(VIEWPORT_SIZE / 2);
root.getChildren().addAll(meshView);
}
private void addPoints() {
mesh.getPoints().addAll(25.255093f, 0.86116815f, 0.9920882f,
28.010185f, 0.6422461f, 0.68806815f,
22.5f, 0.88371015f, 1.0604522f,
20.0f, 0.88371015f, 1.0604522f,
17.5f, 0.88371015f, 1.0604522f,
28.010185f, 0.9249993f, 0.0f,
28.010185f, 0.6422461f, -0.68806815f,
25.255093f, 1.2263886f, 0.0f,
25.255093f, 0.86116815f, -0.9920882f,
22.5f, 1.25f, 0.0f,
20.0f, 1.25f, 0.0f,
17.5f, 1.25f, 0.0f,
22.5f, 0.88371015f, -1.0604522f,
20.0f, 0.88371015f, -1.0604522f,
17.5f, 0.88371015f, -1.0604522f,
28.010185f, -1.4802974E-16f, 0.9898141f,
25.255093f, -7.401487E-17f, 1.4115738f,
25.255093f, -0.86116815f, 0.9920882f,
28.010185f, -0.6422461f, 0.68806815f,
22.5f, 0.0f, 1.5f,
20.0f, 0.0f, 1.5f,
17.5f, 0.0f, 1.5f,
22.5f, -0.88371015f, 1.0604522f,
20.0f, -0.88371015f, 1.0604522f,
17.5f, -0.88371015f, 1.0604522f,
30.0f, 0.0f, 0.0f,
28.010185f, -1.3158199E-16f, -0.9898141f,
25.255093f, -6.5790995E-17f, -1.4115738f,
28.010185f, -0.9249993f, 0.0f,
28.010185f, -0.6422461f, -0.68806815f,
25.255093f, -1.2263886f, 0.0f,
25.255093f, -0.86116815f, -0.9920882f,
22.5f, 0.0f, -1.5f,
20.0f, 0.0f, -1.5f,
17.5f, 0.0f, -1.5f,
22.5f, -1.25f, 0.0f,
20.0f, -1.25f, 0.0f,
17.5f, -1.25f, 0.0f,
22.5f, -0.88371015f, -1.0604522f,
20.0f, -0.88371015f, -1.0604522f,
17.5f, -0.88371015f, -1.0604522f,
15.0f, 0.88371015f, 1.0604522f,
12.5f, 0.88371015f, 1.0604522f,
10.0f, 0.88371015f, 1.0604522f,
7.5f, 0.88371015f, 1.0604522f,
4.744907f, 0.86116815f, 0.9920882f,
1.989814f, 0.6422461f, 0.68806815f,
15.0f, 1.25f, 0.0f,
12.5f, 1.25f, 0.0f,
10.0f, 1.25f, 0.0f,
15.0f, 0.88371015f, -1.0604522f,
12.5f, 0.88371015f, -1.0604522f,
10.0f, 0.88371015f, -1.0604522f,
7.5f, 1.25f, 0.0f,
4.744907f, 1.2263886f, 0.0f,
1.989814f, 0.9249993f, 0.0f,
1.989814f, 0.6422461f, -0.68806815f,
7.5f, 0.88371015f, -1.0604522f,
4.744907f, 0.86116815f, -0.9920882f,
15.0f, 0.0f, 1.5f,
12.5f, 0.0f, 1.5f,
10.0f, 0.0f, 1.5f,
15.0f, -0.88371015f, 1.0604522f,
12.5f, -0.88371015f, 1.0604522f,
10.0f, -0.88371015f, 1.0604522f,
7.5f, 0.0f, 1.5f,
4.744907f, -7.401487E-17f, 1.4115738f,
1.989814f, -1.4802974E-16f, 0.9898141f,
7.5f, -0.88371015f, 1.0604522f,
4.744907f, -0.86116815f, 0.9920882f,
1.989814f, -0.6422461f, 0.68806815f,
15.0f, 0.0f, -1.5f,
12.5f, 0.0f, -1.5f,
10.0f, 0.0f, -1.5f,
15.0f, -1.25f, 0.0f,
12.5f, -1.25f, 0.0f,
10.0f, -1.25f, 0.0f,
15.0f, -0.88371015f, -1.0604522f,
12.5f, -0.88371015f, -1.0604522f,
10.0f, -0.88371015f, -1.0604522f,
0.0f, -2.9605948E-16f, 0.0f,
7.5f, 0.0f, -1.5f,
4.744907f, -6.5790995E-17f, -1.4115738f,
1.989814f, -1.3158199E-16f, -0.9898141f,
7.5f, -1.25f, 0.0f,
4.744907f, -1.2263886f, 0.0f,
1.989814f, -0.9249993f, 0.0f,
1.989814f, -0.6422461f, -0.68806815f,
7.5f, -0.88371015f, -1.0604522f,
4.744907f, -0.86116815f, -0.9920882f);
}
private void addFaces() {
mesh.getFaces().addAll(80, 80, 80, 55, 55, 55, 56, 56, 56,
80, 80, 80, 56, 56, 56, 83, 83, 83,
83, 83, 83, 87, 87, 87, 80, 80, 80,
87, 87, 87, 86, 86, 86, 80, 80, 80,
80, 80, 80, 86, 86, 86, 70, 70, 70,
80, 80, 80, 70, 70, 70, 67, 67, 67,
67, 67, 67, 46, 46, 46, 80, 80, 80,
46, 46, 46, 55, 55, 55, 80, 80, 80,
55, 55, 55, 54, 54, 54, 58, 58, 58,
55, 55, 55, 58, 58, 58, 56, 56, 56,
56, 56, 56, 58, 58, 58, 82, 82, 82,
56, 56, 56, 82, 82, 82, 83, 83, 83,
83, 83, 83, 82, 82, 82, 87, 87, 87,
82, 82, 82, 89, 89, 89, 87, 87, 87,
87, 87, 87, 89, 89, 89, 86, 86, 86,
89, 89, 89, 85, 85, 85, 86, 86, 86,
86, 86, 86, 85, 85, 85, 69, 69, 69,
86, 86, 86, 69, 69, 69, 70, 70, 70,
70, 70, 70, 69, 69, 69, 66, 66, 66,
70, 70, 70, 66, 66, 66, 67, 67, 67,
67, 67, 67, 66, 66, 66, 46, 46, 46,
66, 66, 66, 45, 45, 45, 46, 46, 46,
46, 46, 46, 45, 45, 45, 55, 55, 55,
45, 45, 45, 54, 54, 54, 55, 55, 55,
54, 54, 54, 53, 53, 53, 57, 57, 57,
54, 54, 54, 57, 57, 57, 58, 58, 58,
58, 58, 58, 57, 57, 57, 81, 81, 81,
58, 58, 58, 81, 81, 81, 82, 82, 82,
82, 82, 82, 81, 81, 81, 89, 89, 89,
81, 81, 81, 88, 88, 88, 89, 89, 89,
89, 89, 89, 88, 88, 88, 85, 85, 85,
88, 88, 88, 84, 84, 84, 85, 85, 85,
85, 85, 85, 84, 84, 84, 68, 68, 68,
85, 85, 85, 68, 68, 68, 69, 69, 69,
69, 69, 69, 68, 68, 68, 65, 65, 65,
69, 69, 69, 65, 65, 65, 66, 66, 66,
66, 66, 66, 65, 65, 65, 45, 45, 45,
65, 65, 65, 44, 44, 44, 45, 45, 45,
45, 45, 45, 44, 44, 44, 54, 54, 54,
44, 44, 44, 53, 53, 53, 54, 54, 54,
53, 53, 53, 49, 49, 49, 52, 52, 52,
53, 53, 53, 52, 52, 52, 57, 57, 57,
57, 57, 57, 52, 52, 52, 73, 73, 73,
57, 57, 57, 73, 73, 73, 81, 81, 81,
81, 81, 81, 73, 73, 73, 88, 88, 88,
73, 73, 73, 79, 79, 79, 88, 88, 88,
88, 88, 88, 79, 79, 79, 84, 84, 84,
79, 79, 79, 76, 76, 76, 84, 84, 84,
84, 84, 84, 76, 76, 76, 64, 64, 64,
84, 84, 84, 64, 64, 64, 68, 68, 68,
68, 68, 68, 64, 64, 64, 61, 61, 61,
68, 68, 68, 61, 61, 61, 65, 65, 65,
65, 65, 65, 61, 61, 61, 44, 44, 44,
61, 61, 61, 43, 43, 43, 44, 44, 44,
44, 44, 44, 43, 43, 43, 53, 53, 53,
43, 43, 43, 49, 49, 49, 53, 53, 53,
49, 49, 49, 48, 48, 48, 51, 51, 51,
49, 49, 49, 51, 51, 51, 52, 52, 52,
52, 52, 52, 51, 51, 51, 72, 72, 72,
52, 52, 52, 72, 72, 72, 73, 73, 73,
73, 73, 73, 72, 72, 72, 79, 79, 79,
72, 72, 72, 78, 78, 78, 79, 79, 79,
79, 79, 79, 78, 78, 78, 76, 76, 76,
78, 78, 78, 75, 75, 75, 76, 76, 76,
76, 76, 76, 75, 75, 75, 63, 63, 63,
76, 76, 76, 63, 63, 63, 64, 64, 64,
64, 64, 64, 63, 63, 63, 60, 60, 60,
64, 64, 64, 60, 60, 60, 61, 61, 61,
61, 61, 61, 60, 60, 60, 43, 43, 43,
60, 60, 60, 42, 42, 42, 43, 43, 43,
43, 43, 43, 42, 42, 42, 49, 49, 49,
42, 42, 42, 48, 48, 48, 49, 49, 49,
48, 48, 48, 47, 47, 47, 50, 50, 50,
48, 48, 48, 50, 50, 50, 51, 51, 51,
51, 51, 51, 50, 50, 50, 71, 71, 71,
51, 51, 51, 71, 71, 71, 72, 72, 72,
72, 72, 72, 71, 71, 71, 78, 78, 78,
71, 71, 71, 77, 77, 77, 78, 78, 78,
78, 78, 78, 77, 77, 77, 75, 75, 75,
77, 77, 77, 74, 74, 74, 75, 75, 75,
75, 75, 75, 74, 74, 74, 62, 62, 62,
75, 75, 75, 62, 62, 62, 63, 63, 63,
63, 63, 63, 62, 62, 62, 59, 59, 59,
63, 63, 63, 59, 59, 59, 60, 60, 60,
60, 60, 60, 59, 59, 59, 42, 42, 42,
59, 59, 59, 41, 41, 41, 42, 42, 42,
42, 42, 42, 41, 41, 41, 48, 48, 48,
41, 41, 41, 47, 47, 47, 48, 48, 48,
47, 47, 47, 11, 11, 11, 14, 14, 14,
47, 47, 47, 14, 14, 14, 50, 50, 50,
50, 50, 50, 14, 14, 14, 34, 34, 34,
50, 50, 50, 34, 34, 34, 71, 71, 71,
71, 71, 71, 34, 34, 34, 77, 77, 77,
34, 34, 34, 40, 40, 40, 77, 77, 77,
77, 77, 77, 40, 40, 40, 74, 74, 74,
40, 40, 40, 37, 37, 37, 74, 74, 74,
74, 74, 74, 37, 37, 37, 24, 24, 24,
74, 74, 74, 24, 24, 24, 62, 62, 62,
62, 62, 62, 24, 24, 24, 21, 21, 21,
62, 62, 62, 21, 21, 21, 59, 59, 59,
59, 59, 59, 21, 21, 21, 41, 41, 41,
21, 21, 21, 4, 4, 4, 41, 41, 41, 41,
41, 41, 4, 4, 4, 47, 47, 47, 4, 4, 4,
11, 11, 11, 47, 47, 47, 11, 11, 11,
10, 10, 10, 13, 13, 13, 11, 11, 11,
13, 13, 13, 14, 14, 14, 14, 14, 14,
13, 13, 13, 33, 33, 33, 14, 14, 14,
33, 33, 33, 34, 34, 34, 34, 34, 34,
33, 33, 33, 40, 40, 40, 33, 33, 33,
39, 39, 39, 40, 40, 40, 40, 40, 40,
39, 39, 39, 37, 37, 37, 39, 39, 39,
36, 36, 36, 37, 37, 37, 37, 37, 37,
36, 36, 36, 23, 23, 23, 37, 37, 37,
23, 23, 23, 24, 24, 24, 24, 24, 24,
23, 23, 23, 20, 20, 20, 24, 24, 24,
20, 20, 20, 21, 21, 21, 21, 21, 21,
20, 20, 20, 4, 4, 4, 20, 20, 20,
3, 3, 3, 4, 4, 4, 4, 4, 4,
3, 3, 3, 11, 11, 11, 3, 3, 3,
10, 10, 10, 11, 11, 11, 10, 10, 10,
9, 9, 9, 12, 12, 12, 10, 10, 10,
12, 12, 12, 13, 13, 13, 13, 13, 13,
12, 12, 12, 32, 32, 32, 13, 13, 13,
32, 32, 32, 33, 33, 33, 33, 33, 33,
32, 32, 32, 39, 39, 39, 32, 32, 32,
38, 38, 38, 39, 39, 39, 39, 39, 39,
38, 38, 38, 36, 36, 36, 38, 38, 38,
35, 35, 35, 36, 36, 36, 36, 36, 36,
35, 35, 35, 22, 22, 22, 36, 36, 36,
22, 22, 22, 23, 23, 23, 23, 23, 23,
22, 22, 22, 19, 19, 19, 23, 23, 23,
19, 19, 19, 20, 20, 20, 20, 20, 20,
19, 19, 19, 3, 3, 3, 19, 19, 19,
2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2,
10, 10, 10, 2, 2, 2, 9, 9, 9,
10, 10, 10, 9, 9, 9, 7, 7, 7,
8, 8, 8, 9, 9, 9, 8, 8, 8,
12, 12, 12, 12, 12, 12, 8, 8, 8,
27, 27, 27, 12, 12, 12, 27, 27, 27,
32, 32, 32, 32, 32, 32, 27, 27, 27,
38, 38, 38, 27, 27, 27, 31, 31, 31,
38, 38, 38, 38, 38, 38, 31, 31, 31,
35, 35, 35, 31, 31, 31, 30, 30, 30,
35, 35, 35, 35, 35, 35, 30, 30, 30,
17, 17, 17, 35, 35, 35, 17, 17, 17,
22, 22, 22, 22, 22, 22, 17, 17, 17,
16, 16, 16, 22, 22, 22, 16, 16, 16,
19, 19, 19, 19, 19, 19, 16, 16, 16,
2, 2, 2, 16, 16, 16, 0, 0, 0,
2, 2, 2, 2, 2, 2, 0, 0, 0,
9, 9, 9, 0, 0, 0, 7, 7, 7,
9, 9, 9, 7, 7, 7, 5, 5, 5,
6, 6, 6, 7, 7, 7, 6, 6, 6,
8, 8, 8, 8, 8, 8, 6, 6, 6,
26, 26, 26, 8, 8, 8,
26, 26, 26, 27, 27, 27, 27, 27, 27,
26, 26, 26, 31, 31, 31, 26, 26, 26,
29, 29, 29, 31, 31, 31, 31, 31, 31,
29, 29, 29, 30, 30, 30, 29, 29, 29,
28, 28, 28, 30, 30, 30, 30, 30, 30,
28, 28, 28, 18, 18, 18, 30, 30, 30,
18, 18, 18, 17, 17, 17, 17, 17, 17,
18, 18, 18, 15, 15, 15, 17, 17, 17,
15, 15, 15, 16, 16, 16, 16, 16, 16,
15, 15, 15, 0, 0, 0,
15, 15, 15, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 1, 7, 7, 7,
1, 1, 1, 5, 5, 5, 7, 7, 7,
5, 5, 5, 25, 25, 25, 6, 6, 6,
6, 6, 6, 25, 25, 25, 26, 26, 26,
26, 26, 26, 25, 25, 25, 29, 29, 29,
29, 29, 29, 25, 25, 25, 28, 28, 28,
28, 28, 28, 25, 25, 25, 18, 18, 18,
18, 18, 18, 25, 25, 25, 15, 15, 15,
15, 15, 15, 25, 25, 25, 1, 1, 1,
1, 1, 1, 25, 25, 25, 5, 5, 5);
}
private void addNormals() {
mesh.getNormals().addAll(0.07288012f, 0.768564f, 0.6356083f, 0.21982567f, 0.7893725f, 0.5732083f, 0.012779057f,
0.76441664f, 0.6445959f, 0.0f, 0.76822126f, 0.6401844f, 0.0f, 0.76822126f, 0.6401844f, 0.25024077f, 0.96818364f,
0.0f, 0.21982567f, 0.7893725f, -0.5732083f, 0.07571304f, 0.9971296f, 0.0f, 0.07288012f, 0.768564f, -0.6356083f,
0.0087126205f, 0.99996203f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.012779057f, 0.76441664f, -0.6445959f, 0.0f,
0.76822126f, -0.6401844f, 0.0f, 0.76822126f, -0.6401844f, 0.22647266f, 0.0f, 0.9740175f, 0.07080862f, 0.0f, 0.9974899f,
0.07288012f, -0.768564f, 0.6356083f, 0.21982567f, -0.7893725f, 0.5732083f, 0.011401603f, 0.0f, 0.999935f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.012779057f, -0.76441664f, 0.6445959f, 0.0f, -0.76822126f, 0.6401844f, 0.0f, -0.76822126f, 0.6401844f,
1.0f, 0.0f, 0.0f, 0.22647266f, 0.0f, -0.9740175f, 0.07080862f, 0.0f, -0.9974899f, 0.25024077f, -0.96818364f, 0.0f, 0.21982567f,
-0.7893725f, -0.5732083f, 0.07571304f, -0.9971296f, 0.0f, 0.07288012f, -0.768564f, -0.6356083f, 0.011401603f, 0.0f, -0.999935f,
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0087126205f, -0.99996203f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.012779057f, -0.76441664f,
-0.6445959f, 0.0f, -0.76822126f, -0.6401844f, 0.0f, -0.76822126f, -0.6401844f, 0.0f, 0.76822126f, 0.6401844f, 0.0f, 0.76822126f,
0.6401844f, 0.0f, 0.76822126f, 0.6401844f, -0.009348294f, 0.76747775f, 0.6410074f, -0.07317282f, 0.73539054f, 0.67368126f, -0.2320432f,
0.6365708f, 0.73548186f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.76822126f, -0.6401844f, 0.0f, 0.76822126f, -0.6401844f,
0.0f, 0.76822126f, -0.6401844f, -0.0030446206f, 0.99999535f, 0.0f, -0.044230007f, 0.99902135f, 0.0f, -0.19177821f, 0.9814383f, 0.0f,
-0.2320432f, 0.6365708f, -0.73548186f, -0.009348294f, 0.76747775f, -0.6410074f, -0.07317282f, 0.73539054f, -0.67368126f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.76822126f, 0.6401844f, 0.0f, -0.76822126f, 0.6401844f, 0.0f, -0.76822126f, 0.6401844f,
-0.020870605f, 0.0f, 0.9997822f, -0.1069364f, 0.0f, 0.99426585f, -0.2851421f, 0.0f, 0.95848525f, -0.009348294f, -0.76747775f, 0.6410074f,
-0.07317282f, -0.73539054f, 0.67368126f, -0.2320432f, -0.6365708f, 0.73548186f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -0.76822126f, -0.6401844f, 0.0f, -0.76822126f, -0.6401844f, 0.0f, -0.76822126f,
-0.6401844f, -1.0f, 0.0f, -4.363512E-17f, -0.020870605f, 0.0f, -0.9997822f, -0.1069364f, 0.0f, -0.99426585f, -0.2851421f, 0.0f,
-0.95848525f, -0.0030446206f, -0.99999535f, 0.0f, -0.044230007f, -0.99902135f, 0.0f, -0.19177821f, -0.9814383f, 0.0f, -0.2320432f,
-0.6365708f, -0.73548186f, -0.009348294f, -0.76747775f, -0.6410074f, -0.07317282f, -0.73539054f, -0.67368126f);
}
Color[] colorArray = {Color.rgb(0, 45, 255, 1.0),
Color.rgb(0, 81, 255, 1.0),
Color.rgb(0, 194, 255, 1.0),
Color.rgb(0, 255, 101, 1.0),
Color.rgb(0, 255, 80, 1.0),
Color.rgb(0, 104, 255, 1.0),
Color.rgb(0, 95, 255, 1.0),
Color.rgb(0, 53, 255, 1.0),
Color.rgb(0, 59, 255, 1.0),
Color.rgb(0, 137, 255, 1.0),
Color.rgb(0, 255, 120, 1.0),
Color.rgb(0, 255, 79, 1.0),
Color.rgb(0, 203, 255, 1.0),
Color.rgb(0, 255, 100, 1.0),
Color.rgb(0, 255, 79, 1.0),
Color.rgb(0, 51, 255, 1.0),
Color.rgb(0, 21, 255, 1.0),
Color.rgb(0, 0, 255, 1.0),
Color.rgb(0, 38, 255, 1.0),
Color.rgb(0, 241, 255, 1.0),
Color.rgb(0, 255, 83, 1.0),
Color.rgb(0, 255, 80, 1.0),
Color.rgb(0, 167, 255, 1.0),
Color.rgb(0, 255, 104, 1.0),
Color.rgb(0, 255, 80, 1.0),
Color.rgb(0, 148, 255, 1.0),
Color.rgb(0, 65, 255, 1.0),
Color.rgb(0, 35, 255, 1.0),
Color.rgb(0, 61, 255, 1.0),
Color.rgb(0, 52, 255, 1.0),
Color.rgb(0, 7, 255, 1.0),
Color.rgb(0, 15, 255, 1.0),
Color.rgb(0, 248, 255, 1.0),
Color.rgb(0, 255, 83, 1.0),
Color.rgb(0, 255, 80, 1.0),
Color.rgb(0, 101, 255, 1.0),
Color.rgb(0, 255, 126, 1.0),
Color.rgb(0, 255, 80, 1.0),
Color.rgb(0, 176, 255, 1.0),
Color.rgb(0, 255, 103, 1.0),
Color.rgb(0, 255, 80, 1.0),
Color.rgb(0, 255, 117, 1.0),
Color.rgb(0, 255, 152, 1.0),
Color.rgb(0, 255, 100, 1.0),
Color.rgb(255, 246, 0, 1.0),
Color.rgb(255, 28, 0, 1.0),
Color.rgb(255, 52, 0, 1.0),
Color.rgb(0, 255, 104, 1.0),
Color.rgb(0, 255, 152, 1.0),
Color.rgb(0, 255, 143, 1.0),
Color.rgb(0, 255, 117, 1.0),
Color.rgb(0, 255, 152, 1.0),
Color.rgb(0, 255, 102, 1.0),
Color.rgb(155, 255, 0, 1.0),
Color.rgb(255, 36, 0, 1.0),
Color.rgb(255, 55, 0, 1.0),
Color.rgb(255, 65, 0, 1.0),
Color.rgb(255, 255, 0, 1.0),
Color.rgb(255, 42, 0, 1.0),
Color.rgb(0, 255, 128, 1.0),
Color.rgb(0, 255, 151, 1.0),
Color.rgb(0, 255, 59, 1.0),
Color.rgb(0, 255, 117, 1.0),
Color.rgb(0, 255, 151, 1.0),
Color.rgb(0, 255, 95, 1.0),
Color.rgb(255, 134, 0, 1.0),
Color.rgb(255, 5, 0, 1.0),
Color.rgb(255, 39, 0, 1.0),
Color.rgb(255, 216, 0, 1.0),
Color.rgb(255, 0, 0, 1.0),
Color.rgb(255, 11, 0, 1.0),
Color.rgb(0, 255, 129, 1.0),
Color.rgb(0, 255, 152, 1.0),
Color.rgb(0, 255, 62, 1.0),
Color.rgb(0, 255, 105, 1.0),
Color.rgb(0, 255, 151, 1.0),
Color.rgb(0, 255, 141, 1.0),
Color.rgb(0, 255, 117, 1.0),
Color.rgb(0, 255, 151, 1.0),
Color.rgb(0, 255, 97, 1.0),
Color.rgb(255, 93, 0, 1.0),
Color.rgb(255, 146, 0, 1.0),
Color.rgb(255, 19, 0, 1.0),
Color.rgb(255, 53, 0, 1.0),
Color.rgb(178, 255, 0, 1.0),
Color.rgb(255, 0, 0, 1.0),
Color.rgb(255, 12, 0, 1.0),
Color.rgb(255, 25, 0, 1.0),
Color.rgb(255, 226, 0, 1.0),
Color.rgb(255, 0, 0, 1.0),};
private Image colorPalette(Color[] colors) {
int numColors = colors.length;
int width = (int) Math.sqrt(numColors);
int height = numColors / width;
WritableImage img = new WritableImage(width, height);
PixelWriter pw = img.getPixelWriter();
//float[] colors = buffer.array();
AtomicInteger count = new AtomicInteger();
IntStream.range(0, height).boxed()
.forEach(y -> IntStream.range(0, width).boxed()
.forEach(x -> pw.setColor(x, y, getColor(count))));
// save for testing purposes
try {
ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", new File("palette" + ".png"));
} catch (IOException ex) {
}
return img;
}
private Color getColor(AtomicInteger count) {
return colorArray[count.getAndIncrement()];
}
private float[] getTextureLocation(int iPoint, int numColors) {
int width = (int) Math.sqrt(numColors);
int height = numColors / width;
int y = iPoint / width;
int x = iPoint - width * y;
float[] textureArray = new float[]{(((float) x) / ((float) width)), (((float) y) / ((float) height))};
return textureArray;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
This is my output:
and this is the expected output:
As pointed out in the question you mentioned, you need:
A texture image, basically a small png where each pixel has a color that will be later looked up.
You have created one, but it seems the colors are randomly distributed:
A way to map the vertices of the mesh to a pixel in the image.
The faces in your mesh define the indices of the points, normals and textures.
I.e., your face 0 is 80, 80, 80, 55, 55, 55, 56, 56, 56, and that means that your texture indices are 80, 55, 56.
According to your mapping (getTextureLocation), these indices have coordinates:
55 [0.11111111, 0.6]
56 [0.22222222, 0.6]
80 [0.8888889, 0.8]
which are the colors:
As you can see that these vertices are using exactly that color:
With this random coloring, for each pair (x, y) within the face 0, the texture is interpolated between those values.
You can verify this by enabling PickResult on mouse pressed:
scene.setOnMousePressed(event -> {
PickResult pickResult = event.getPickResult();
if (pickResult != null) {
System.out.println("face: " + pickResult.getIntersectedFace());
System.out.println("point: " + pickResult.getIntersectedPoint());
System.out.println("text: " + pickResult.getIntersectedTexCoord());
}
}
For instance, for a point in-between 55 and 80, it gives [x = 0.51, y = 0.71], which is expected: {(0.9 + 0.1)/2, (0.6+0.8)/2)}. In other words, it will go from color(55) to color(80), using all the colors in that range:
Obviously, this is not what you want, but it is doing what you have told it to do.
The trick here is to have a texture with a linear gradient of colors, so when the interpolation is done, the differences are small.
For instance, this:
private Color getColor(AtomicInteger count, int numColors) {
int iColor = count.getAndIncrement();
java.awt.Color c = java.awt.Color.getHSBColor((float) iColor / (float) numColors, 1.0f, 1.0f);
return Color.rgb(c.getRed(), c.getGreen(), c.getBlue());
}
will give you this image:
and this result:
Which is closer to what you want, but not there yet.
The final trick is using a mapping between your texture indices, which are based on the vertices, based on some mathematical function.
Using a function f(x, y, z) based on the vertex coordinates, it should give you a value between the minimum and maximum colors. This color has an index, and that index is the one that you should use for the texture.
As a quick use case here, I'll use f(x, y, z) = x, based on your desired result.
Since in your case, x goes from 0 to 30, you can tweak the texture location mapping easily:
float[] points = new float[mesh.getPoints().size()];
mesh.getPoints().toArray(points);
IntStream.range(0, numVertices).boxed()
.forEach(i -> {
double x = points[3 * i];
int fact = (int) (x / 30d * numVertices);
mesh.getTexCoords().addAll(getTextureLocation(fact, numColors));
});
with this result, based in the gradient I defined:
Now it is up to you to generate the proper texture image and texture mapping.
References
For further references, have a look at FXyz3D library. A bunch of primitive 3D shapes are created using a TexturedMesh class that allows texturing a mesh with colors, 3D or 1D mapping, and face or pattern coloring.
Without an example it is difficult to tell what is going wrong. But I think you are on the wrong track anyway. The question is what do you expect to happen when the resulting triangles of the triangle mesh are filled. Just think about how many colored areas you would have to create and manage in your texture if you allow arbitrary combinations of color triples for the vertices of one triangle.
Is there any way to change the title sizes of a ctree plot?
Use the following variables to quickly set up a ctree plot
a<-c(41, 45, 50, 50, 38, 42, 50, 43, 37, 22, 42, 48, 47, 48, 50, 47, 41, 50, 45, 45, 39, 45, 46, 48, 50, 47, 50, 21, 48, 50, 48, 48, 48, 46, 36, 38, 50, 39, 44, 44, 50, 49, 40, 48, 48, 45, 39, 40, 44, 39, 40, 44, 42, 39, 49, 50, 50, 48, 48, 47, 48, 47, 44, 41, 50, 47, 50, 41, 50, 44, 47, 50, 24, 40, 43, 37, 44, 32, 43, 42, 44, 38, 42, 45, 50, 47, 46, 43,
37, 47, 37, 45, 41, 50, 42, 32, 43, 48, 45, 45, 28, 44,38, 41, 45, 48, 48, 47 ,49, 16, 45, 50, 47, 50, 43, 49, 50)
X1<-c(NA,NA,NA,NA,NA,1,2,2,2,NA,2,2,2,2,2,2,2,NA,NA,2,2,2,2,NA,2,2,2,2,2,2,2,NA,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,NA,2,2,2,2,2,2,2,2,2,2,NA,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2)
X2<-c(NA,NA,NA,NA,NA,NA,2,2,2,NA,NA,2,2,2,2,2,2,NA,2,2,2,2,2,NA,2,2,2,2,2,2,2,NA,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,NA,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2)
X3<-c(NA,35,40,NA,10,NA,31,NA,14,NA,NA,15,17,NA,NA,16,10,15,14,39,17,35,14,14,22,10,15,0,34,23,13,35,32,2,14,10,14,10,10,10,40,10,13,13,10,10,10,13,13,25,10,35,NA,13,NA,10,40,0,0,20,40,10,14,40,10,10,10,10,13,10,8,NA,NA,14,NA,10,28,10,10,15,15,16,10,10,35,16,NA,NA,NA,NA,30,19,14,30,10,10,8,10,21,10,10,35,15,34,10,39,NA,10,10,6,16,10,10,10,10,34,10)
X4<-c(NA,NA,511,NA,NA,NA,NA,NA,849,NA,NA,NA,NA,1324,1181,832,1005,166,204,1253,529,317,294,NA,514,801,534,1319,272,315,572,96,666,236,842,980,290,843,904,528,27,366,540,560,659,107,63,20,1184,1052,214,46,139,310,872,891,651,687,434,1115,1289,455,764,938,1188,105,757,719,1236,982,710,NA,NA,632,NA,546,747,941,1257,99,133,61,249,NA,NA,1080,NA,645,19,107,486,1198,276,777,738,1073,539,1096,686,505,104,5,55,553,1023,1333,NA,NA,969,691,1227,1059,358,991,1019,NA,1216)
p<-cbind(X1,X2,X3,X4)
With the following you should then get the plot below
library(party)
urp<-ctree(a~., data=data.frame(a,p))
plot(urp, main = "Broken Title")
How do I change the title size? I've tried the following which does nothing:
plot(urp, main = "Broken Title",cex = 1.5)
plot(urp, main = "Broken Title",cex.main = 1.5)
In fact, can I manipulate the title at all? font.main similarly does nothing. What about the titles "Node 2" and "Node 3." Is there likewise no way for me to manipulate them?
A similar question was asked here:
https://stackoverflow.com/questions/18817522/ctree-changing-titles-of-inner-nodes
There is good news and bad news.
So the plot() function that's actually doing all the work there is party:::plot.BinaryTree. The help is available from ?plot.BinaryTree but the bad news is it doesn't have any easily accessible parameters for font formatting. However, the good news is that the function uses grid graphics to draw to the screen and you can update properties after you've created the plot.
So after you run
library(party)
urp<-ctree(a~., data=data.frame(a,p))
plot(urp, main = "Broken Title")
You can run
for(gg in grid.ls(print=F)[[1]]) {
if (grepl("text", gg)) {
print(paste(gg, grid.get(gg)$label,sep=": "))
}
}
to see all the text boxes on the plot. For example, I see
[1] "GRID.text.673: Broken Title"
[1] "GRID.text.677: X1"
[1] "GRID.text.678: p = 0.03"
[1] "GRID.text.680: 1"
[1] "GRID.text.682: phantom(0) <= 1"
[1] "GRID.text.684: phantom(0) > 1"
[1] "GRID.text.686: Node 2 (n = 8)"
[1] "GRID.text.697: Node 3 (n = 109)"
Here i see the node names, and the text they contain. Note that the node names are not the same from plot to plot and change everything you draw the same plot. But you can use this list to find the ones you want to change and update them. So if I wanted to make the main text bigger, I would run
grid.edit("GRID.text.673", gp=gpar(fontsize=20))
or If i wanted to italize the node labels i would run
grid.edit("GRID.text.686", gp=gpar(fontface=3))
grid.edit("GRID.text.697", gp=gpar(fontface=3))
and that gives