Zoom program with Integrator class
in
Programming Questions
•
1 year ago
I am using an integrator class to get a smooth zoom into a specific zone on a map (mine is only slightly modified from the one
here with
this code). With mine, when a person enters each character of a zip code the points on a map with that code highlight and zoom in a level closer without having to click to enable the zoom (and I don't use faders like the code linked above).
Problem I am having is I need the "bounds" variables to update (line 152) with new mins and max's (of the highlighted points) so that when I call calcZoom() (line 162) the span, target, etc. values update and I get the zoom effect. For some reason though, I can't get accurate new min's and max's of the highlighted points (I tried on line 306 first with test max and min variables but the max's and mins being found are not the maxes and mins of the highlighted/chosen xx and yy variables). I have no idea why.
The original values of maxes and mins are correct (line 57-60) and the xx, yy values are correct so why wont lines 306-310 find the max and min of those?
Thank you for the help. I know this is a large chunk of code for a forum question.
McKinnley
Problem I am having is I need the "bounds" variables to update (line 152) with new mins and max's (of the highlighted points) so that when I call calcZoom() (line 162) the span, target, etc. values update and I get the zoom effect. For some reason though, I can't get accurate new min's and max's of the highlighted points (I tried on line 306 first with test max and min variables but the max's and mins being found are not the maxes and mins of the highlighted/chosen xx and yy variables). I have no idea why.
- PFont font;
- String[] data;
- String typedString = ""; //Why don't I have to say String typedString = new String("");
- char typedChars[] = new char[5];
- Place[] places;
- int totalCount, zip, typedCount, foundCount;
- int placeCount = 0;
- int typedPartials[] = new int[6];
- float Xmin, Xmax, Ymin, Ymax, x, y;
- float mapX1, mapX2, mapY1, mapY2;
- float textX, textY;
- String name;
- color backgroundColor = color(152, 151, 141);
- color highlightedColor = color(247, 237, 25);
- color dormantColor = color(162, 156, 30);
- //Temporary troubleshooting variables
- float XminTest;
- float XmaxTest;
- float YminTest;
- float YmaxTest;
- //Zoom
- Integrator zoomDepth = new Integrator();
- Integrator zoomX1;
- Integrator zoomX2;
- Integrator zoomY1;
- Integrator zoomY2;
- float targetX1[] = new float[6];
- float targetX2[] = new float[6];
- float targetY1[] = new float[6];
- float targetY2[] = new float[6];
- //Boundary of currently valid points at this typedCount
- float boundsX1, boundsY1;
- float boundsX2, boundsY2;
- PrintWriter file;
- void setup() {
- size(720, 453, P3D);
- file = createWriter("file.txt");
- mapX1 = 30.0;
- mapX2 = width - mapX1;
- mapY1 = 20.0;
- mapY2 = height - mapY1;
- font = loadFont("AgencyFB-Reg-48.vlw");
- textFont(font);
- textMode(SCREEN);
- textX = 30;
- textY = height - 10;
- readData(data); //output is Place(zip name x y)
- zoomX1 = new Integrator(Xmin);
- zoomX2 = new Integrator(Xmax);
- zoomY1 = new Integrator(Ymin);
- zoomY2 = new Integrator(Ymax);
- XminTest = width;
- XmaxTest = 0;
- YminTest = height;
- YmaxTest = 0;
- targetX1[0] = Xmin;
- targetX2[0] = Xmax;
- targetY1[0] = Ymin;
- targetY2[0] = Ymax;
- //ellipseMode(CENTER);
- frameRate(15);
- }
- public void draw() {
- background(backgroundColor);
- updateAnimation();
- println(XminTest+" "+XmaxTest+" "+YminTest+" "+YmaxTest);
- for(int i=0; i<placeCount; i++) {
- places[i].draw();
- }
- }
- void updateAnimation() {
- if(foundCount>0) {
- zoomDepth.target(typedCount);
- } else {
- zoomDepth.target(typedCount-1);
- }
- zoomDepth.update();
- zoomX1.update();
- zoomX2.update();
- zoomY1.update();
- zoomY2.update();
- }
- float TX(float x) {
- float xx = map(x, zoomX1.value, zoomX2.value, mapX1, mapX2);
- return xx;
- }
- float TY(float y) {
- float yy = map(y, zoomY1.value, zoomY2.value, mapY2, mapY1);
- return yy;
- }
- void readData(String[] data) {
- data = loadStrings("data/correctCoords.tsv");
- parseInfo(data[0]);
- places = new Place[totalCount];
- for(int i=1; i<data.length; i++) {
- places[placeCount] = parsePlace(data[i]);
- placeCount++;
- }
- }
- //read header line
- void parseInfo(String head) {
- String[] pieces = split(head, TAB);
- totalCount = int(pieces[0]);
- Xmin = float(pieces[1]);
- Xmax = float(pieces[2]);
- Ymin = float(pieces[3]);
- Ymax = float(pieces[4]);
- }
- Place parsePlace(String pLine) {
- String[] pieces = split(pLine, TAB);
- zip = int(pieces[0]);
- x = float(pieces[1]);
- y = float(pieces[2]);
- name = pieces[3];
- return new Place(zip, name, x, y);
- }
- void keyPressed() {
- if(key == BACKSPACE || key == DELETE) {
- if(typedCount > 0) {
- typedCount--;
- }
- updateTyped();
- }
- else if(key>='0' && key<='9') {
- if(typedCount!=5) {
- if(foundCount > 0) {
- typedChars[typedCount++] = key; //why go the the next typed count and ignore the first?
- }
- }
- }
- updateTyped();
- }
- void updateTyped() {
- typedString = new String(typedChars, 0, typedCount);
- typedPartials[typedCount] = int(typedString);
- for(int j=typedCount-1;j>0; --j){
- typedPartials[j] = typedPartials[j+1]/10;
- }
- foundCount = 0;
- //set bounds to new mins and maxes
- boundsX1 = Xmin;
- boundsX2 = Xmax;
- boundsY1 = Ymin;
- boundsY2 = Ymax;
- for(int i=0; i<placeCount; i++) {
- places[i].check();
- }
- calcZoom();
- }
- void calcZoom() {
- if(foundCount != 0) {
- float spanX = (boundsX2-boundsX1);
- float spanY = (boundsY2-boundsY1);
- float midX = (boundsX1+boundsX2)/2;
- float midY = (boundsY1+boundsY2)/2;
- if((spanX != 0) && (spanY != 0)) {
- float screenAspect = width/float(height);
- float spanAspect = spanX/spanY;
- if(spanAspect>screenAspect) {
- spanY = (spanX/width)*height;
- }else {
- spanX = (spanY/height)*width;
- }
- } else {
- spanX = targetX2[typedCount-1] - targetX1[typedCount-1];
- spanY = targetY2[typedCount-1] - targetY1[typedCount-1];
- }
- targetX1[typedCount] = midX -spanX/2;
- targetX2[typedCount] = midX +spanX/2;
- targetY1[typedCount] = midY -spanY/2;
- targetY2[typedCount] = midY +spanY/2;
- } else if(typedCount != 0) {
- targetX1[typedCount] = targetX1[typedCount-1];
- targetX2[typedCount] = targetX2[typedCount-1];
- targetY1[typedCount] = targetY1[typedCount-1];
- targetY2[typedCount] = targetY2[typedCount-1];
- }
- zoomX1.target(targetX1[typedCount]);
- zoomX2.target(targetX2[typedCount]);
- zoomY1.target(targetY1[typedCount]);
- zoomY2.target(targetY2[typedCount]);
- println(targetX1[typedCount]);
- println(targetX2[typedCount]);
- println(targetY1[typedCount]);
- println(targetY2[typedCount]);
- zoomX1.set(zoomX1.target);
- zoomX2.set(zoomX2.target);
- zoomY1.set(zoomY1.target);
- zoomY2.set(zoomY2.target);
- }
- public class Integrator {
- static final float ATTRACTION = 0.2f; // formerly 0.1f
- static final float DAMPING = 0.5f; // formerly 0.9f
- float value = 0;
- float vel = 0;
- float accel = 0;
- float force = 0;
- float mass = 1;
- float damping;
- float attraction;
- boolean targeting;
- float target;
- public Integrator() {
- this.value = 0;
- this.damping = DAMPING;
- this.attraction = ATTRACTION;
- }
- public Integrator(float value) {
- this.value = value;
- this.damping = DAMPING;
- this.attraction = ATTRACTION;
- }
- public Integrator(float value, float attraction, float damping) {
- this.value = value;
- this.damping = damping;
- this.attraction = attraction;
- }
- public void set(float v) {
- value = v;
- }
- public float get() {
- return value;
- }
- public void setAttraction(float a) {
- attraction = a;
- }
- public void setDamping(float d) {
- damping = d;
- }
- public boolean update() {
- if (targeting) {
- force += attraction * (target - value);
- accel = force / mass;
- vel = (vel + accel) * damping;
- value += vel;
- force = 0;
- return (vel > 0.0001f);
- }
- return false;
- }
- public void target(float t) {
- targeting = true;
- target = t;
- }
- }
- class Place {
- String name;
- int zip;
- float x;
- float y;
- int partial[];
- int matchDepth;
- Place(int zip, String name, float x, float y) {
- this.name = name;
- this.zip = zip;
- this.x = x;
- this.y = y;
- partial = new int[6];
- partial[5] = zip;
- partial[4] = partial[5]/10;
- partial[3] = partial[4]/10;
- partial[2] = partial[3]/10;
- partial[1] = partial[2]/10;
- }
- void draw() {
- color c = dormantColor;
- float xx = TX(x);
- float yy = TY(y);
- if(typedCount != 0) {
- if(matchDepth == typedCount) {
- c = highlightedColor;
- //find new mins and maxs of highlighted places to set as new bounds
- if(xx <= XminTest) {XminTest = xx;}
- if(xx >= XmaxTest) {XmaxTest = xx;}
- if(yy <= YminTest) {YminTest = yy;}
- if(yy >= YmaxTest) {YmaxTest = yy;}
- //println(xx +" "+ yy+" "+ XminTest +" "+ XmaxTest+" "+ YminTest+" "+YmaxTest);
- }
- else {
- c = dormantColor;
- }
- }
- noStroke();
- fill(c);
- ellipse(xx, yy, 2, 2);
- text(typedString, textX, textY);
- }
- void check() {
- if(typedCount != 0) {
- for(int j=typedCount; j>0; --j) {
- if(typedPartials[j] == partial[j]) {
- matchDepth = j;
- break;
- }
- }
- }
- if(matchDepth == typedCount) {
- foundCount++;
- }
- }
- }
The original values of maxes and mins are correct (line 57-60) and the xx, yy values are correct so why wont lines 306-310 find the max and min of those?
Thank you for the help. I know this is a large chunk of code for a forum question.
McKinnley
1