CollisionOutline_Impl::CollisionOutline_Impl(const std::vector<Contour> &new_contours, const Size &new_base_size, OutlineAccuracy accuracy ) : do_inside_test(false), width(0), height(0), angle(0), minimum_enclosing_disc(0.0f,0.0f,0.0f), position(0,0), scale_factor(1,1), translation_offset(0,0), translation_origin(origin_top_left), rotation_hotspot(0,0), rotation_origin(origin_center), collision_info_points(false), collision_info_normals(false), collision_info_meta(false), collision_info_pen_depth(false), collision_info_collect(false) { contours = new_contours; width = new_base_size.width; height = new_base_size.height; //minimum_enclosing_disc set by calculate_radius() int check_distance = 3; switch( accuracy ) { case accuracy_high: optimize(check_distance, PI / 7.0f); break; case accuracy_medium: optimize(check_distance, PI / 6.0f); break; case accuracy_low: optimize(check_distance, PI / 5.0f); break; case accuracy_poor: optimize(check_distance, PI / 4.0f); break; case accuracy_raw: break; default: break; } calculate_radius(); calculate_sub_circles(); }
void hsyncnet::process(const double order, const solve_type solver, const bool collect_dynamic, hsyncnet_analyser & analyser) { std::size_t number_neighbors = m_initial_neighbors; std::size_t current_number_clusters = m_oscillators.size(); if (current_number_clusters <= m_number_clusters) { return; /* Nothing to process, amount of objects is less than required amount of clusters. */ } double radius = average_neighbor_distance(oscillator_locations, number_neighbors); std::size_t increase_step = (std::size_t) round(oscillator_locations->size() * m_increase_persent); if (increase_step < 1) { increase_step = DEFAULT_INCREASE_STEP; } sync_dynamic current_dynamic; do { create_connections(radius, false); simulate_dynamic(order, 0.1, solver, collect_dynamic, current_dynamic); if (collect_dynamic) { if (analyser.empty()) { store_state(*(current_dynamic.begin()), analyser); } store_state(*(current_dynamic.end() - 1), analyser); } else { m_time += DEFAULT_TIME_STEP; } hsyncnet_cluster_data clusters; current_dynamic.allocate_sync_ensembles(0.05, clusters); current_number_clusters = clusters.size(); number_neighbors += increase_step; radius = calculate_radius(radius, number_neighbors); } while(current_number_clusters > m_number_clusters); if (!collect_dynamic) { store_state(*(current_dynamic.end() - 1), analyser); } }
void CollisionOutline_Impl::set_scale(float new_scale_x, float new_scale_y) { if( scale_factor.x == new_scale_x && scale_factor.y == new_scale_y ) return; if (new_scale_x == 0 || new_scale_y == 0) return; float scale_x = new_scale_x / scale_factor.x; float scale_y = new_scale_y / scale_factor.y; for (unsigned int outer_cnt = 0; outer_cnt < contours.size(); outer_cnt++) { Contour *contour_ptr = &contours[outer_cnt]; std::vector<Pointf>::size_type point_size = contour_ptr->get_points().size(); for (int inner_cnt = 0; inner_cnt < point_size; inner_cnt++) { contour_ptr->get_points()[inner_cnt].x = position.x + ((contour_ptr->get_points()[inner_cnt].x-position.x)*scale_x); contour_ptr->get_points()[inner_cnt].y = position.y + ((contour_ptr->get_points()[inner_cnt].y-position.y)*scale_y); } } // we can skip this recalculation (if its a unit-scale) if(new_scale_x == new_scale_y) { minimum_enclosing_disc.position.x = position.x + ((minimum_enclosing_disc.position.x-position.x)*scale_x); minimum_enclosing_disc.position.y = position.y + ((minimum_enclosing_disc.position.y-position.y)*scale_y); minimum_enclosing_disc.radius *= (new_scale_x/scale_factor.x); // TODO: we should be able to scale these too (if calculate_sub_circles(); } else { calculate_sub_circles(); calculate_radius(); } scale_factor.x = new_scale_x; scale_factor.y = new_scale_y; }