VEX find closest float value to target?

   1041   5   0
User Avatar
Member
21 posts
Joined: 4月 2019
Offline
My knowledge of VEX is fairly newborn. So I'm having a hard time figuring out how I can achieve my goal here.
in my vex script, I have a series of float values. These values change depending on the geometry. for the sake of simplicity, let's say this is what I have:

float a=11.5;
float b-23;
float c=48.9;
float d=90.2;

float target=45;

What could I write here to look through those float values and automatically pick whichever one is closest to the target?
Thoughts and ideas are very much appreciated. Thanks!
Edited by Poliigon - 2023年2月21日 14:12:21
User Avatar
Member
670 posts
Joined: 9月 2013
Offline
Hi Poliigon,

you could iterate over an array and store the index and update the minimal absolute difference to the target value.

float vals[] = array(12.3, 34.1, 54.7, 67.9);
float target = 40.0;

float d_min = 10000.0;
int index = -1;

foreach(int i; float val; vals){
    float d = abs(val - target);
    if(d < d_min){
        d_min = d;
        index = i;
    }
}

f@closest_value = vals[index];

Alternatively you just set the float values as positions of a point cloud and use the nearpoint()-function.
https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
21 posts
Joined: 4月 2019
Offline
Konstantin Magnus
Hi Poliigon,

you could iterate over an array and store the index and update the minimal absolute difference to the target value.

float vals[] = array(12.3, 34.1, 54.7, 67.9);
float target = 40.0;

float d_min = 10000.0;
int index = -1;

foreach(int i; float val; vals){
    float d = abs(val - target);
    if(d < d_min){
        d_min = d;
        index = i;
    }
}

f@closest_value = vals[index];

Alternatively you just set the float values as positions of a point cloud and use the nearpoint()-function.

Thanks a lot!

I'm very curious about the point cloud idea, as I had thought of that as well. Though I am unsure how to set the position of points based on those float values. If you have a minute, would you mind breaking that down?
User Avatar
Member
670 posts
Joined: 9月 2013
Offline
You would overwrite the position:

v@P = set(f@val, 0.0, 0.0);

and search for the closest match:

float target = chf('target');

vector pos = set(target, 0, 0);
int pt_near = nearpoint(0, pos);

i@group_target = pt_near == i@ptnum;

Attachments:
target_val.hipnc (129.6 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
21 posts
Joined: 4月 2019
Offline
Konstantin Magnus
You would overwrite the position:

v@P = set(f@val, 0.0, 0.0);

and search for the closest match:

float target = chf('target');

vector pos = set(target, 0, 0);
int pt_near = nearpoint(0, pos);

i@group_target = pt_near == i@ptnum;

You're a legend. Thanks mate!
User Avatar
Member
4486 posts
Joined: 2月 2012
Offline
If you have so many values in a sorted state i.e. in the millions or billions, you can also use binary search to speed up the search exponentially:
https://en.wikipedia.org/wiki/Binary_search_algorithm [en.wikipedia.org]

However Konstantin's methods are already very established for practically any case.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
  • Quick Links