|
|
@ -6,13 +6,73 @@ TSNEMap::TSNEMap(){ |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::setup(){ |
|
|
|
for (int i = 0; i < 5; ++i) { |
|
|
|
setupNodes(); |
|
|
|
// Setup FBO
|
|
|
|
fbo.allocate(ofGetWindowWidth() / 3, ofGetWindowHeight() / 3 * 2, GL_RGBA); |
|
|
|
cam.removeAllInteractions(); |
|
|
|
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY,OF_MOUSE_BUTTON_LEFT); |
|
|
|
cam.enableOrtho(); |
|
|
|
// Setup top-down orthographic camera
|
|
|
|
cam.setNearClip(-1000000); |
|
|
|
cam.setFarClip(1000000); |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::setupTSNE(std::string jsonPath){ |
|
|
|
// Load in JSON
|
|
|
|
jsonEmbeddings = ofLoadJson(jsonPath); |
|
|
|
|
|
|
|
// Check if JSON is an array
|
|
|
|
if (!jsonEmbeddings.is_array()) { |
|
|
|
ofLogError() << "JSON is not an array"; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// Loop through each entry in the JSON array
|
|
|
|
for (const auto& entry : jsonEmbeddings) { |
|
|
|
// Check if the entry has a "vector" field
|
|
|
|
if (entry.contains("vector") && entry["vector"].is_array()) { |
|
|
|
std::vector<float> vec; |
|
|
|
|
|
|
|
// Loop through each value in the "vector" field
|
|
|
|
for (const auto& value : entry["vector"]) { |
|
|
|
// Check if the value is a number and add it to the vector
|
|
|
|
if (value.is_number()) { |
|
|
|
vec.push_back(value.get<float>()); |
|
|
|
} else { |
|
|
|
ofLogError() << "Vector value is not a number"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Add the extracted vector to the list
|
|
|
|
embeddings.push_back(vec); |
|
|
|
} else { |
|
|
|
ofLogError() << "Entry does not contain a valid 'vector' field"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Run tsne
|
|
|
|
tsnePoints = tsne.run(embeddings, dims, perplexity, theta, normalise, runManually); |
|
|
|
|
|
|
|
// Output the vectors to the console (for debugging)
|
|
|
|
for (const auto& vec : tsnePoints) { |
|
|
|
for (float value : vec) { |
|
|
|
std::cout << value << " "; |
|
|
|
} |
|
|
|
std::cout << std::endl; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::setupNodes(){ |
|
|
|
|
|
|
|
int idx = 0; |
|
|
|
|
|
|
|
for (const auto& vec : tsnePoints) { |
|
|
|
ofImage img; |
|
|
|
ImageObject obj; |
|
|
|
ofPlanePrimitive plane; |
|
|
|
|
|
|
|
img.load("images/happy.png"); |
|
|
|
// what image?
|
|
|
|
img.load(jsonEmbeddings[idx]["image"]); |
|
|
|
|
|
|
|
int imageW = image.getWidth(); |
|
|
|
int imageH = image.getHeight(); |
|
|
@ -47,7 +107,7 @@ void TSNEMap::setup(){ |
|
|
|
} |
|
|
|
|
|
|
|
plane.set(planeW, planeH); // Random width and height
|
|
|
|
plane.setPosition(ofRandom(-200, 200), ofRandom(-200, 200), 0); // Random position on XZ plane
|
|
|
|
plane.setPosition((vec[0] * 5000) - 2500, (vec[1] * 5000) - 2500, 0); // Random position on XZ plane
|
|
|
|
plane.setResolution(2, 2); |
|
|
|
plane.mapTexCoordsFromTexture(img.getTexture()); |
|
|
|
|
|
|
@ -61,16 +121,10 @@ void TSNEMap::setup(){ |
|
|
|
obj.phaseY = ofRandom(0, TWO_PI); // Random phase
|
|
|
|
|
|
|
|
objects.push_back(obj); |
|
|
|
|
|
|
|
idx++; |
|
|
|
} |
|
|
|
|
|
|
|
// Setup FBO
|
|
|
|
fbo.allocate(ofGetWindowWidth() / 3, ofGetWindowHeight() / 3 * 2, GL_RGBA); |
|
|
|
cam.removeAllInteractions(); |
|
|
|
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY,OF_MOUSE_BUTTON_LEFT); |
|
|
|
cam.enableOrtho(); |
|
|
|
// Setup top-down orthographic camera
|
|
|
|
cam.setNearClip(-1000000); |
|
|
|
cam.setFarClip(1000000); |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::update(){ |
|
|
|