RetroX
|
|
Posted on: December 20, 2010, 09:02:53 pm |
|
|
Master of all things Linux
Location: US Joined: Apr 2008
Posts: 1055
|
#include <limits> double distance_to_object_point(int object) { enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); double distance = std::numeric_limits<double>::infinity(); double tempdist; for (enigma::inst_iter *it = enigma::fetch_inst_iter_by_int(object); it != NULL; it = it->next) { const enigma::object_collisions* inst2 = (enigma::object_collisions*)it->inst; if (inst1 == inst2) continue; tempdist = point_distance(inst1->x, inst1->y, inst2->x, inst2->y); if (tempdist < distance) { distance = tempdist; } } return (distance == std::numeric_limits<double>::infinity() ? 0 : distance); }
inline double dist_ranges(double left1, double right1, double left2, double right2) { double right = min(right1, right2), left = max(left1, left2); return (left > right ? left - right : 0); }
double distance_to_object_bbox(int object) { enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); const double left1 = inst1->x + inst1->bbox_left, top1 = inst1->y + inst1->bbox_top, right1 = inst1->x + inst1->bbox_right, bottom1 = inst1->y + inst1->bbox_bottom; double distance = std::numeric_limits<double>::infinity(); double tempdist; for (enigma::inst_iter *it = enigma::fetch_inst_iter_by_int(object); it != NULL; it = it->next) { const enigma::object_collisions* inst2 = (enigma::object_collisions*)it->inst; if (inst1 == inst2) continue; const double left2 = inst2->x + inst1->bbox_left, top2 = inst2->y + inst1->bbox_top, right2 = inst2->x + inst1->bbox_right, bottom2 = inst2->y + inst1->bbox_bottom; tempdist = hypot(dist_ranges(left1, right1, left2, right2), dist_ranges(top1, bottom1, top2, bottom2)); if (tempdist < distance) { distance = tempdist; } } return (distance == std::numeric_limits<double>::infinity() ? 0 : distance); } Tested and both work. I don't know which method that GM uses, but here's two different algorithms.
|
|
« Last Edit: December 25, 2010, 10:54:31 am by RetroX »
|
Logged
|
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)Why do all the pro-Microsoft people have troll avatars?
|
|
|
Post made December 22, 2010, 06:33:33 am was deleted at the author's request.
|
|
Josh @ Dreamland
|
|
Reply #3 Posted on: December 23, 2010, 09:51:47 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Issue is, I don't know what GM does either. It does compensate for something like a bbox, but I'm not sure if it calculates the distance between the closest two points in the entirety of either mask, or if it calculates the distance between those along a straight line, or if it just defaults to bbox (which would be the only reasonable method), and if in that case it uses a rotated bbox or just a standard one... I'm in the dark on it. But I might accept Retro's bottom function. Provided, of course, that dist_ranges be made inline or into a macro.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
Post made December 24, 2010, 01:41:27 pm was deleted at the author's request.
|
|
|
polygone
|
|
Reply #7 Posted on: December 26, 2010, 01:46:45 pm |
|
|
Location: England Joined: Mar 2009
Posts: 794
|
Thought that was probably the case, was just wondering why Retro looped through instead of using the with statement. So thought it might be due to speed.
|
|
« Last Edit: December 26, 2010, 01:52:22 pm by polygone »
|
Logged
|
I honestly don't know wtf I'm talking about but hopefully I can muddle my way through.
|
|
|
Post made December 26, 2010, 01:51:05 pm was deleted at the author's request.
|
|
polygone
|
|
Reply #10 Posted on: December 26, 2010, 02:00:05 pm |
|
|
Location: England Joined: Mar 2009
Posts: 794
|
OK I'll keep that in mind.
|
|
|
Logged
|
I honestly don't know wtf I'm talking about but hopefully I can muddle my way through.
|
|
|
Josh @ Dreamland
|
|
Reply #11 Posted on: December 26, 2010, 06:16:01 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Not to mention, enigma::fetch_inst_iter_by_int(object) is literally as efficient as can be. It is, in fact, the function that composes with(). It is set up such that there is no way to make it any faster; the iterator it returns accounts for all aspects of instance iteration, including ID, object index with heredity, and keywords such as all, other, or noone.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
RetroX
|
|
Reply #12 Posted on: December 27, 2010, 06:06:53 pm |
|
|
Master of all things Linux
Location: US Joined: Apr 2008
Posts: 1055
|
Updated code:
/* ********************* */ // Place this in some math header or something. inline double range_difference(double left1, double right1, double left2, double right2) { double right = min(right1, right2), left = max(left1, left2); return (left > right ? left - right : 0); } /* ********************* */
#include <limits>
double distance_to_object_point(int object) { enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); double distance = std::numeric_limits<double>::infinity(); double tempdist; for (enigma::inst_iter *it = enigma::fetch_inst_iter_by_int(object); it != NULL; it = it->next) { const enigma::object_collisions* inst2 = (enigma::object_collisions*)it->inst; if (inst1 == inst2) continue; tempdist = point_distance(inst1->x, inst1->y, inst2->x, inst2->y); if (tempdist < distance) { distance = tempdist; } } return (distance == std::numeric_limits<double>::infinity() ? 0 : distance); }
double distance_to_object_bbox(int object) { enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); const double left1 = inst1->x + inst1->bbox_left, top1 = inst1->y + inst1->bbox_top, right1 = inst1->x + inst1->bbox_right, bottom1 = inst1->y + inst1->bbox_bottom; double distance = std::numeric_limits<double>::infinity(); double tempdist; for (enigma::inst_iter *it = enigma::fetch_inst_iter_by_int(object); it != NULL; it = it->next) { const enigma::object_collisions* inst2 = (enigma::object_collisions*)it->inst; if (inst1 == inst2) continue; const double left2 = inst2->x + inst1->bbox_left, top2 = inst2->y + inst1->bbox_top, right2 = inst2->x + inst1->bbox_right, bottom2 = inst2->y + inst1->bbox_bottom; tempdist = hypot(range_difference(left1, right1, left2, right2), range_difference(top1, bottom1, top2, bottom2)); if (tempdist < distance) { distance = tempdist; } } return (distance == std::numeric_limits<double>::infinity() ? 0 : distance); }
inline double distance_to_point_point(double x, double y) { enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); return point_distance(inst1->x, inst1->y, x, y); }
inline double distance_to_point_bbox(double x, double y) { enigma::object_collisions* const inst1 = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); const double left1 = inst1->x + inst1->bbox_left, top1 = inst1->y + inst1->bbox_top, right1 = inst1->x + inst1->bbox_right, bottom1 = inst1->y + inst1->bbox_bottom; return hypot(abs(min(left1 - x, right1 -x), min(top1 - x, bottom1 -x))); }
// Possible option in configuration to choose which method is used? inline double distance_to_object(int object) { return distance_to_object_bbox(object); } inline double distance_to_point(double x, double y) { return distance_to_point_bbox(x, y); } I'm almost certain that someone will modify this before it's put into ENIGMA, but this is what I have.
|
|
« Last Edit: December 27, 2010, 10:48:11 pm by RetroX »
|
Logged
|
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)Why do all the pro-Microsoft people have troll avatars?
|
|
|
|
polygone
|
|
Reply #14 Posted on: December 27, 2010, 06:46:35 pm |
|
|
Location: England Joined: Mar 2009
Posts: 794
|
I still prefer this:
return (distance == std::numeric_limits<double>::infinity() ? -1 : distance);
|
|
|
Logged
|
I honestly don't know wtf I'm talking about but hopefully I can muddle my way through.
|
|
|
|