|
|
@ -1,8 +1,13 @@ |
|
|
|
#include "TSNEMap.h" |
|
|
|
#include "Request.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TSNEMap::TSNEMap(){ |
|
|
|
image.load("images/happy.jpeg"); |
|
|
|
zoomLevel = 1.0; |
|
|
|
zoomLevel = 1; |
|
|
|
velocity = glm::vec3(0.0f,0.0f,0.0f); |
|
|
|
acceleration = glm::vec3(0.0f,0.0f,0.0f); |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::setup(){ |
|
|
@ -15,6 +20,8 @@ void TSNEMap::setup(){ |
|
|
|
// Setup top-down orthographic camera
|
|
|
|
cam.setNearClip(-1000000); |
|
|
|
cam.setFarClip(1000000); |
|
|
|
cam.setPosition(0, 0, 0); |
|
|
|
cam.setScale(zoomLevel, zoomLevel, zoomLevel); |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::setupTSNE(std::string jsonPath){ |
|
|
@ -32,6 +39,10 @@ void TSNEMap::setupTSNE(std::string jsonPath){ |
|
|
|
// Check if the entry has a "vector" field
|
|
|
|
if (entry.contains("vector") && entry["vector"].is_array()) { |
|
|
|
std::vector<float> vec; |
|
|
|
std::string imagePath; |
|
|
|
ImageHM imageEntry; |
|
|
|
|
|
|
|
imagePath = entry["image"]; |
|
|
|
|
|
|
|
// Loop through each value in the "vector" field
|
|
|
|
for (const auto& value : entry["vector"]) { |
|
|
@ -45,6 +56,11 @@ void TSNEMap::setupTSNE(std::string jsonPath){ |
|
|
|
|
|
|
|
// Add the extracted vector to the list
|
|
|
|
embeddings.push_back(vec); |
|
|
|
|
|
|
|
imageEntry.imagePath = imagePath; |
|
|
|
imageEntry.vec = vec; |
|
|
|
imageMap.push_back(imageEntry); |
|
|
|
|
|
|
|
} else { |
|
|
|
ofLogError() << "Entry does not contain a valid 'vector' field"; |
|
|
|
} |
|
|
@ -54,12 +70,14 @@ void TSNEMap::setupTSNE(std::string jsonPath){ |
|
|
|
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; |
|
|
|
for (size_t i = 0; i < tsnePoints.size(); ++i){ |
|
|
|
const auto& vec = tsnePoints[i]; |
|
|
|
auto& imgHM = imageMap[i]; |
|
|
|
imgHM.position = glm::vec2(vec[0], vec[1]); |
|
|
|
|
|
|
|
imageHashmap[imgHM.imagePath] = imgHM.position; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::setupNodes(){ |
|
|
@ -127,7 +145,11 @@ void TSNEMap::setupNodes(){ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::update(){ |
|
|
|
void TSNEMap::update(std::string imagePath){ |
|
|
|
|
|
|
|
bool imageCheck = false; |
|
|
|
|
|
|
|
|
|
|
|
if (!image.isAllocated()){ |
|
|
|
ofLogError() << "Image not found"; |
|
|
|
} |
|
|
@ -142,6 +164,15 @@ void TSNEMap::update(){ |
|
|
|
|
|
|
|
object.plane.setPosition(object.plane.getPosition().x + offsetX, object.plane.getPosition().y + offsetY, 0); |
|
|
|
} |
|
|
|
|
|
|
|
if (imageHashmap.find(imagePath) != imageHashmap.end()){ |
|
|
|
glm::vec2 position = imageHashmap[imagePath]; |
|
|
|
|
|
|
|
// Move camera to image
|
|
|
|
MoveCameraToPosition(position); |
|
|
|
} else { |
|
|
|
ofLogError() << "Image not found in HashMap"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::draw(){ |
|
|
@ -176,6 +207,45 @@ void TSNEMap::draw(){ |
|
|
|
fbo.draw(0, 0, ofGetWindowWidth() / 3, ofGetWindowHeight() / 3 * 2); |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::MoveCameraToPosition(glm::vec2 position){ |
|
|
|
|
|
|
|
glm::vec3 currentPosition(cam.getPosition().x, cam.getPosition().y, 0); |
|
|
|
glm::vec3 targetPosition((position.x * 5000) - 2500, (position.y * 5000) - 2500, 0); |
|
|
|
glm::vec3 direction = targetPosition - currentPosition; |
|
|
|
float distance = glm::length(direction); |
|
|
|
|
|
|
|
direction = glm::normalize(direction); |
|
|
|
|
|
|
|
// Define acceleration based on direction
|
|
|
|
acceleration = direction * 0.002f; // Adjust as needed
|
|
|
|
|
|
|
|
// Add acceleration to velocity
|
|
|
|
velocity += acceleration; |
|
|
|
|
|
|
|
// Define minimum and maximum velocities based on distance
|
|
|
|
const float minVelocity = 0.01f; // Minimum velocity when close to the target
|
|
|
|
const float maxVelocityDistance = 1000.0f; // Distance at which max velocity is applied
|
|
|
|
const float maxVelocity = 5.0f; // Maximum velocity
|
|
|
|
|
|
|
|
// Scale max velocity based on distance
|
|
|
|
float dynamicMaxVelocity = glm::clamp(distance / maxVelocityDistance * maxVelocity, minVelocity, maxVelocity); |
|
|
|
|
|
|
|
// Clamp the velocity to the range [-dynamicMaxVelocity, dynamicMaxVelocity]
|
|
|
|
float velocityLength = glm::length(velocity); |
|
|
|
if (velocityLength > dynamicMaxVelocity) { |
|
|
|
velocity = glm::normalize(velocity) * dynamicMaxVelocity; |
|
|
|
} |
|
|
|
|
|
|
|
// Update position
|
|
|
|
glm::vec3 newPosition = currentPosition + velocity; |
|
|
|
cam.setPosition(newPosition); |
|
|
|
|
|
|
|
// Optionally, log the details
|
|
|
|
std::cout << "velocity " << velocity << std::endl; |
|
|
|
std::cout << "target " << targetPosition << std::endl; |
|
|
|
std::cout << "new position " << cam.getPosition() << std::endl; |
|
|
|
} |
|
|
|
|
|
|
|
void TSNEMap::setTexture(std::string imagePath){ |
|
|
|
image.load("images/rte-archive-football/" + imagePath); |
|
|
|
} |
|
|
|