I am trying to make an app that displays a large amount of data as an image. I am creating and displaying the image through CImg. Since it is a very large dataset (~4,000,000 data points) I need to be able to zoom into a certain location on the image. The function I have so far only resizes around the top left image of the screen. Code:
#include <iostream>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include "cimg.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
#include <cmath>
using namespace cimg_library;
int size_x = 640;
int size_y = 480;
int size_z = 1;
int numberOfColorChannels = 3; // R G B
unsigned char initialValue = 0;
CImg<unsigned char> image(size_x, size_y, size_z, numberOfColorChannels, initialValue);
CImgDisplay display(image, "PingMap");
long float ycoor[10000000] = { 0 }, xcoorop[10000000], xcoor[10000000] = { 0 };
long int LO = 0;
char f;
char currentIp[15];
int pingtime;
unsigned int iterator;
void calcMap(int x, int (&rgb)[3]) {
int r = 4.18485e-6 * x * x * x - 0.00532377 * x * x + 2.19321 * x - 39.1125;
int g = 1.28826e-10 * x * x * x * x * x - 1.64251e-7 * x * x * x * x + 6.73208e-5 * x * x * x - 0.00808127 * x * x + 0.280643 * x - 1.61706;
int b = 9.48804e-12 * x * x * x * x * x - 1.05015e-8 * x * x * x * x + 4.19544e-5 * x * x * x - 0.0232532 * x * x + 3.24907 * x + 30.466;
std::cout << " " << max(0, r) << " " << max(0, g) << " " << max(0, b) << ", ";
rgb[0] = max(0, r);
rgb[1] = max(0, g);
rgb[2] = max(0, b);
}
int ping(const char* ip) {
HANDLE hIcmpFile;
unsigned long ipaddr = INADDR_NONE;
DWORD dwRetVal = 0;
DWORD dwError = 0;
char SendData[] = "Data Buffer";
LPVOID ReplyBuffer = NULL;
DWORD ReplySize = 0;
ipaddr = inet_addr(ip);
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
printf("err ");
return -1;
}
// Allocate space for a single reply.
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData) + 8;
ReplyBuffer = (VOID*)malloc(ReplySize);
if (ReplyBuffer == NULL) {
printf("err ");
return -1;
}
dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL,
ipaddr, SendData, sizeof(SendData), NULL,
ReplyBuffer, ReplySize, 1000);
if (dwRetVal != 0) {
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
switch (pEchoReply->Status) {
case IP_DEST_HOST_UNREACHABLE:
printf("unreachable ");
return -1;
case IP_DEST_NET_UNREACHABLE:
printf("unreachable ");
return -1;
case IP_REQ_TIMED_OUT:
printf("unreachable ");
return -1;
default:
break;
}
return pEchoReply->RoundTripTime;
}
else {
printf("unreachable ");
return -1;
}
printf("??? ");
return -1;
}
void move(int j, float h, float& x, float& y)
{
sprintf_s(currentIp, sizeof(currentIp), "%d.%d.%d.%d",
(iterator & 0xFF000000) >> 24,
(iterator & 0x00FF0000) >> 16,
(iterator & 0x0000FF00) >> 8,
(iterator & 0x000000FF));
iterator++;
pingtime = ping(currentIp);
if (pingtime < 0) pingtime = 0;
else pingtime = 432 - (pingtime * 10);
if (j == 1) y -= h;
else if (j == 2) x += h;
else if (j == 3) y += h;
else if (j == 4) x -= h;
std::cout << currentIp << ", ";
int col[3] = { 0,0,0 };
calcMap(pingtime, col);
std::cout << ", ";
image.draw_point((int)x, (int)y, col);
std::cout << pingtime << "\n";
xcoor[LO] += x;
ycoor[LO] += y;
LO++;
}
void hilbert(int r, int d, int t, int u, int i, float h, float& x, float& y)
{
if (i > 0)
{
i--;
hilbert(d, r, u, t, i, h, x, y);
move(r, h, x, y);
hilbert(r, d, t, u, i, h, x, y);
move(d, h, x, y);
hilbert(r, d, t, u, i, h, x, y);
move(t, h, x, y);
hilbert(u, t, d, r, i, h, x, y);
}
}
int factor = 0;
CImg<unsigned char> zoom(CImg<unsigned char> src, int dir) {
factor += 10 * dir;
CImg<unsigned char> img(src);
img.resize(
src.width() + factor,
src.height() + factor,
1,
3);
src.clear();
src.draw_image(img);
return src;
}
int main()
{
int n;
float h = 1;
int r = 2, d = 3, t = 4, u = 1; // X and Y Starting; H is how far it moves; r = rotation?; d, t, u Dosent matter;
float xO = 0, yO = 0, x, y;
n = 11;
x = xO; y = yO;
hilbert(r, d, t, u, n, h, x, y); // Start the Recursive alg;
while (!display.is_closed()) {
display.wait();
if (display.button()) {
if (display.button() & 1) imgdraw = zoom(image, 1);
if (display.button() & 2) imgdraw = zoom(image, -1);
}
imgdraw.display(display);
}
return 0;
}
The zoom()
function is what I have so far. I already tried using the centering_x
and centering_y
parameters, but that just made the image move to those coordinates after resizing. How do I make it resize around a certain point?