float AABB::GetSquaredDistance(const Vector& v) const { const Vector ClosestPoint = GetClosestPoint(v); const Vector Offset = ClosestPoint - v; const float DistSq = Offset.LengthSquared(); return DistSq; }
wxRealPoint MorphanView::GetRealPosition(const wxPoint& point) { wxRealPoint ret = panel->CalcUnscrolledPosition(point); bool snapped = false; if (snap_points) { wxRealPoint closest = GetClosestPoint(ret); if (distance(ret, closest) < SNAP_SENSITIVITY) { ret = closest; snapped = true; } } if (snap_grid && !snapped) { float gridw = grid_width * zoom; float gridh = grid_height * zoom; ret.x = round(point.x / gridw) * gridw; ret.y = round(point.y / gridh) * gridh; } ret.x = ret.x / zoom; ret.y = ret.y / zoom; return ret; }
////////// // Find parameters of the point on a surface that is locally closest to // the test_point. The search for a local close point starts at // seed parameters. If a sub_domain parameter is not NULL, then // the search is restricted to the specified portion of the surface. // // true if returned if the search is successful. false is returned if // the search fails. ON_BOOL32 ON_PlaneSurface::GetLocalClosestPoint( const ON_3dPoint& test_point, // test_point double s0, double t0, // seed_parameters double* s,double* t, // parameters of local closest point returned here const ON_Interval* sdomain, // first parameter sub_domain const ON_Interval* tdomain // second parameter sub_domain ) const { // for planes, global serach is fast and returns same answer as local search return GetClosestPoint(test_point,s,t,0.0,sdomain,tdomain); }
float SplineCurve::GetQuickDistance(Vector2D ref) const { if (type == BICUBIC) { float lens[] = { GetClosestSegmentDistance(p1, p2, ref), GetClosestSegmentDistance(p2, p3, ref), GetClosestSegmentDistance(p3, p4, ref), GetClosestSegmentDistance(p4, p1, ref), GetClosestSegmentDistance(p1, p3, ref), GetClosestSegmentDistance(p2, p4, ref) }; return *std::min_element(lens, lens + 6); } return (GetClosestPoint(ref) - ref).Len(); }
ON_BOOL32 ON_LineCurve::GetLocalClosestPoint( const ON_3dPoint& test_point, double seed_parameter, double* t, const ON_Interval* sub_domain ) const { if ( sub_domain ) { if ( seed_parameter < sub_domain->Min() ) seed_parameter = sub_domain->Min(); else if ( seed_parameter > sub_domain->Max() ) seed_parameter = sub_domain->Max(); } ON_BOOL32 rc = GetClosestPoint( test_point, t, 0.0, sub_domain ); if ( rc && t && seed_parameter != *t && test_point.DistanceTo(PointAt(seed_parameter)) <= test_point.DistanceTo(PointAt(*t)) ) { *t = seed_parameter; } return rc; }
//============================================================================= void Update(float dt) { // selecting unit INT2 tile((cursor_pos.x + cam_pos.x)/32, (cursor_pos.y + cam_pos.y)/32); if(tile.x >= 0 && tile.y >= 0 && tile.x < MAP_W && tile.y < MAP_W && MousePressedRelease(1)) { Tile& t = mapa[tile.x+tile.y*MAP_W]; selected = t.unit; } // sleep button if(player && player->alive && player->inside_building && cursor_pos.x >= 32 && cursor_pos.y >= 700 && cursor_pos.x < 32+16 && cursor_pos.y < 700+16 && MousePressedRelease(1)) { if(player->gold >= 10 && !player->sleeping && player->hp != player->base->hp) { player->gold -= 10; player->sleeping = true; player->sleeping_progress = 0.f; } } // update player if(player && player->alive && player->waiting <= 0.f && !player->moving) { Unit& u = *player; if(player->sleeping) { player->sleeping_progress += dt; if(player->sleeping_progress >= 1.f) { player->hp += 5; player->sleeping_progress = 0.f; if(player->hp >= player->base->hp) { player->hp = player->base->hp; player->sleeping = false; } } } else if(u.inside_building) { // unit inside building, press SPACE to exit if(KeyPressedRelease(SDL_SCANCODE_SPACE) && !mapa[u.pos.x+u.pos.y*MAP_W].unit) { if(!TryMove(u, DIR_S, false)) { if(rand()%2 == 0) { if(!TryMove(u, DIR_SW, false)) { if(TryMove(u, DIR_SE, false)) u.inside_building = false; } else u.inside_building = false; } else { if(!TryMove(u, DIR_SE, false)) { if(TryMove(u, DIR_SW, false)) u.inside_building = false; } else u.inside_building = false; } } else u.inside_building = false; } } else { struct Key1 { SDL_Scancode k1; SDL_Scancode k2; DIR dir; }; const Key1 keys1[] = { SDL_SCANCODE_LEFT, SDL_SCANCODE_KP_4, DIR_W, SDL_SCANCODE_RIGHT, SDL_SCANCODE_KP_6, DIR_E, SDL_SCANCODE_UP, SDL_SCANCODE_KP_8, DIR_N, SDL_SCANCODE_DOWN, SDL_SCANCODE_KP_2, DIR_S }; struct Key2 { SDL_Scancode k1; SDL_Scancode k2; SDL_Scancode k3; DIR dir; }; const Key2 keys2[] = { SDL_SCANCODE_KP_1, SDL_SCANCODE_LEFT, SDL_SCANCODE_DOWN, DIR_SW, SDL_SCANCODE_KP_3, SDL_SCANCODE_RIGHT, SDL_SCANCODE_DOWN, DIR_SE, SDL_SCANCODE_KP_7, SDL_SCANCODE_LEFT, SDL_SCANCODE_UP, DIR_NW, SDL_SCANCODE_KP_9, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, DIR_NE }; for(int i=0; i<4; ++i) { if(KeyDown(keys2[i].k1) || (KeyDown(keys2[i].k2) && KeyDown(keys2[i].k3))) { if(TryMove(u, keys2[i].dir, true)) break; } } if(!u.moving && u.waiting <= 0.f) { for(int i=0; i<4; ++i) { if(KeyDown(keys1[i].k1) || KeyDown(keys1[i].k2)) { if(TryMove(u, keys1[i].dir, true)) break; } } } } } // update ai for(vector<Unit*>::iterator it = units.begin(), end = units.end(); it != end; ++it) { Unit& u = **it; u.attack_timer -= dt; if(u.hp <= 0) { if(&u == player) player = NULL; if(u.moving) mapa[u.new_pos.x+u.new_pos.y*MAP_W].unit = NULL; mapa[u.pos.x+u.pos.y*MAP_W].unit = NULL; delete &u; it = units.erase(it); end = units.end(); if(it == end) break; } else if(u.waiting > 0.f) u.waiting -= dt; else if(u.moving) { u.move_progress += dt*u.base->move_speed; if(u.move_progress >= 1.f) { u.moving = false; mapa[u.pos.x+u.pos.y*MAP_W].unit = NULL; u.pos = u.new_pos; Tile& tile = mapa[u.pos.x+u.pos.y*MAP_W]; if(tile.building) { tile.unit = NULL; u.inside_building = true; if(player->untaxed_gold) { int tax = player->untaxed_gold*TAX/100; player->untaxed_gold -= tax; player->gold += player->untaxed_gold; player->untaxed_gold = 0; } } } } else if(&u != player && player && player->alive && !player->inside_building) { INT2 enemy_pt; int dist = GetClosestPoint(u.pos, *player, enemy_pt); if(dist <= 50) { if(dist <= 15) { // in attack range if(u.attack_timer <= 0.f) { Hit& hit = Add1(hits); hit.pos = player->GetPos(); hit.timer = 0.5f; hit._ref = player->_ref; u.waiting = 0.5f; u.attack_timer = 1.f/u.base->attack_speed; player->hp -= u.base->attack - player->base->defense; if(player->hp <= 0) { player->alive = false; u.gold += (player->gold + player->untaxed_gold); player->gold = 0; player->untaxed_gold = 0; } } } else { DIR dir = GetDir(u.pos, enemy_pt); if(!TryMove(u, dir, false)) { struct SubDir { DIR a, b; }; const SubDir sub_dir[8] = { DIR_SE, DIR_SW, //DIR_S, DIR_W, DIR_S, //DIR_SW, DIR_NW, DIR_SW, //DIR_W, DIR_N, DIR_W, //DIR_NW, DIR_NE, DIR_NW, //DIR_N, DIR_N, DIR_E, //DIR_NE, DIR_SE, DIR_NE, //DIR_E, DIR_S, DIR_E //DIR_SE, }; if(rand()%2 == 0) { if(!TryMove(u, sub_dir[dir].a, false)) TryMove(u, sub_dir[dir].b, false); } else { if(!TryMove(u, sub_dir[dir].b, false)) TryMove(u, sub_dir[dir].a, false); } } } } } } // update hit animations for(vector<Hit>::iterator it = hits.begin(), end = hits.end(); it != end;) { Hit& hit = *it; hit.timer -= dt; if(hit.timer <= 0.f) { if(it+1 == end) { hits.pop_back(); break; } else { std::iter_swap(it, end-1); hits.pop_back(); end = hits.end(); } } else { if(CheckRef(hit._ref)) hit.pos = hit._ref->GetRef().GetPos(); ++it; } } // set camera if(player) { cam_pos = player->GetPos() - SCREEN_SIZE/2; if(cam_pos.x < 0) cam_pos.x = 0; if(cam_pos.y < 0) cam_pos.y = 0; if(cam_pos.x + SCREEN_SIZE.x > MAP_W*32) cam_pos.x = MAP_W*32-SCREEN_SIZE.x; if(cam_pos.y + SCREEN_SIZE.y > MAP_H*32) cam_pos.y = MAP_H*32-SCREEN_SIZE.y; } }
Float HawkLine3D::GetDistance(const HawkVector3D& oVec) const { HawkVector3D vPt = GetClosestPoint(oVec); return (oVec - vPt).Length(); }
Float HawkRay2D::GetDistance(const HawkVector2D& oVec2) const { return (oVec2 - GetClosestPoint(oVec2)).Length(); }
Vector Triangle::GetClosestPoint( const Vector& v ) const { return GetClosestPoint( v, NULL ); }