double MDL_PAR(iteratortype st, iteratortype en) { double d1 = d_euc(*st, *en); double PER_DIST=0, ANG_DIST=0; iteratortype it = st; iteratortype it2 = it; it2 ++; while (true) { double d2 = d_euc(*it, *it2); if (d1 >= d2) { PER_DIST += perpen_dist(*st,*en,*it,*it2); ANG_DIST += angle_dist(*st,*en,*it,*it2); }else{ PER_DIST += perpen_dist(*it,*it2,*st,*en); ANG_DIST += angle_dist(*it,*it2,*st,*en); } if (it2 == en) break; it ++; it2 ++; } // information calculation double LH = log2(d1); double LDH = log2(PER_DIST) + log2(ANG_DIST); return LH + LDH; }
double total_dist(point &si,point &ei,point &sj,point &ej, double w_perpendicular=0.33, double w_parallel=0.33, double w_angle=0.33) { double td = w_perpendicular * perpen_dist(si,ei,sj,ej) + w_parallel * par_dist(si,ei,sj,ej) + w_angle * angle_dist(si,ei,sj,ej); return td; }
// eccentricity: 0->circle, limit->1: line EllipseGenerator get_ellipse_generator(Eigen::Vector2f center_span, Eigen::Vector2f radius_span, float min_r_ratio, float min_arc_angle, float sigma) { std::uniform_real_distribution<float> center_dist(center_span(0), center_span(1)); std::uniform_real_distribution<float> radius_dist(radius_span(0), radius_span(1)); std::uniform_real_distribution<float> angle_dist(0, 2*M_PI); // Center. float cx = center_dist(G_engine); float cy = center_dist(G_engine); // Rotation. Doesn't make sense to rotate ellipse more than 180 deg. float angle = angle_dist(G_engine); if (angle > M_PI) angle -= M_PI; // Radii; ratio of minor/major radii must not be < min_r_ratio float a, b; do { a = radius_dist(G_engine); b = radius_dist(G_engine); if (a < b) std::swap(a, b); } while (b/a < min_r_ratio); // Arc span; must be at least min_arc_angle float phi_min, phi_max; do { phi_min = angle_dist(G_engine); phi_max = angle_dist(G_engine); if (phi_max < phi_min) std::swap(phi_max, phi_min); } while (phi_max - phi_min < min_arc_angle); EllipseGeometry geometry{Eigen::Vector2f(cx, cy), Eigen::Vector2f(a, b), angle}; return EllipseGenerator(geometry, Eigen::Vector2f(phi_min, phi_max), sigma); }
/* ************************************************************************* * * ****** st_SRotation: * ************************************************************************* */ TEST( C99_CommonBeamElementDriftTests, MinimalAddToBufferCopyRemapRead ) { using size_t = ::st_buffer_size_t; using object_t = ::st_Object; using raw_t = unsigned char; using belem_t = ::st_SRotation; using real_t = SIXTRL_REAL_T; static real_t const ZERO = real_t{ 0.0 }; static real_t const EPS = real_t{ 1e-13 }; /* --------------------------------------------------------------------- */ std::mt19937_64::result_type const seed = 20180830u; std::mt19937_64 prng; prng.seed( seed ); using angle_dist_t = std::uniform_real_distribution< real_t >; angle_dist_t angle_dist( real_t{ -1.57079632679 }, real_t{ +1.57079632679 } ); static SIXTRL_CONSTEXPR_OR_CONST size_t NUM_BEAM_ELEMENTS = size_t{ 1000 }; ::st_object_type_id_t const BEAM_ELEMENT_TYPE_ID = ::st_OBJECT_TYPE_SROTATION; std::vector< belem_t > orig_beam_elements( NUM_BEAM_ELEMENTS, belem_t{} ); size_t const slot_size = ::st_BUFFER_DEFAULT_SLOT_SIZE; size_t const num_objs = NUM_BEAM_ELEMENTS; size_t const num_garbage = size_t{ 0 }; size_t const num_dataptrs = size_t{ 0 }; size_t num_slots = size_t{ 0 }; for( size_t ii = size_t{ 0 } ; ii < NUM_BEAM_ELEMENTS ; ++ii ) { real_t const angle = angle_dist( prng ); belem_t* ptr_srot = ::st_SRotation_preset( &orig_beam_elements[ ii ] ); ASSERT_TRUE( ptr_srot != nullptr ); ::st_SRotation_set_angle( ptr_srot, angle ); ASSERT_TRUE( EPS > std::fabs( std::cos( angle ) - ::st_SRotation_get_cos_angle( ptr_srot ) ) ); ASSERT_TRUE( EPS > std::fabs( std::sin( angle ) - ::st_SRotation_get_sin_angle( ptr_srot ) ) ); real_t const cmp_angle = ::st_SRotation_get_angle( ptr_srot ); real_t const delta = std::fabs( angle - cmp_angle ); if( EPS <= std::fabs( delta ) ) { std::cout << "here" << std::endl; } ASSERT_TRUE( EPS > std::fabs( angle - ::st_SRotation_get_angle( ptr_srot ) ) ); num_slots += ::st_ManagedBuffer_predict_required_num_slots( nullptr, sizeof( ::st_SRotation ), ::st_SRotation_get_num_dataptrs( ptr_srot ), nullptr, nullptr, slot_size ); } /* --------------------------------------------------------------------- */ size_t const requ_buffer_size = ::st_ManagedBuffer_calculate_buffer_length( nullptr, num_objs, num_slots, num_dataptrs, num_garbage, slot_size ); ::st_Buffer* eb = ::st_Buffer_new( requ_buffer_size ); ASSERT_TRUE( eb != nullptr ); /* --------------------------------------------------------------------- */ size_t be_index = size_t{ 0 }; belem_t* ptr_orig = &orig_beam_elements[ be_index++ ]; ASSERT_TRUE( ptr_orig != nullptr ); object_t* ptr_object = ::st_Buffer_add_object( eb, ptr_orig, sizeof( belem_t ), BEAM_ELEMENT_TYPE_ID, ::st_SRotation_get_num_dataptrs( ptr_orig ), nullptr, nullptr, nullptr ); ASSERT_TRUE( ptr_object != nullptr ); ASSERT_TRUE( ::st_Buffer_get_num_of_objects( eb ) == be_index ); ASSERT_TRUE( ::st_Object_get_const_begin_ptr( ptr_object ) != nullptr ); ASSERT_TRUE( ::st_Object_get_size( ptr_object ) >= sizeof( belem_t ) ); ASSERT_TRUE( ::st_Object_get_type_id( ptr_object ) == BEAM_ELEMENT_TYPE_ID ); belem_t* ptr_srot = reinterpret_cast< belem_t* >( ::st_Object_get_begin_ptr( ptr_object ) ); ASSERT_TRUE( ptr_srot != nullptr ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( ptr_srot ) - ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_cos_angle( ptr_srot ) - ::st_SRotation_get_cos_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_sin_angle( ptr_srot ) - ::st_SRotation_get_sin_angle( ptr_orig ) ) ); /* --------------------------------------------------------------------- */ ptr_orig = &orig_beam_elements[ be_index++ ]; ptr_srot = ::st_SRotation_new( eb ); ASSERT_TRUE( ptr_srot != nullptr ); ASSERT_TRUE( ::st_Buffer_get_num_of_objects( eb ) == be_index ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( ptr_srot ) - ZERO ) ); ::st_SRotation_set_angle( ptr_srot, ::st_SRotation_get_angle( ptr_orig ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( ptr_srot ) - ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_cos_angle( ptr_srot ) - ::st_SRotation_get_cos_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_sin_angle( ptr_srot ) - ::st_SRotation_get_sin_angle( ptr_orig ) ) ); /* --------------------------------------------------------------------- */ ptr_orig = &orig_beam_elements[ be_index++ ]; ptr_srot = ::st_SRotation_add( eb, ::st_SRotation_get_angle( ptr_orig ) ); ASSERT_TRUE( ptr_srot != nullptr ); ASSERT_TRUE( ::st_Buffer_get_num_of_objects( eb ) == be_index ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( ptr_srot ) - ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_cos_angle( ptr_srot ) - ::st_SRotation_get_cos_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_sin_angle( ptr_srot ) - ::st_SRotation_get_sin_angle( ptr_orig ) ) ); /* --------------------------------------------------------------------- */ ptr_orig = &orig_beam_elements[ be_index++ ]; ptr_srot = ::st_SRotation_add_detailed( eb, std::cos( ::st_SRotation_get_angle( ptr_orig ) ), std::sin( ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( ptr_srot != nullptr ); ASSERT_TRUE( ::st_Buffer_get_num_of_objects( eb ) == be_index ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( ptr_srot ) - ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_cos_angle( ptr_srot ) - ::st_SRotation_get_cos_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_sin_angle( ptr_srot ) - ::st_SRotation_get_sin_angle( ptr_orig ) ) ); for( ; be_index < NUM_BEAM_ELEMENTS ; ) { ptr_orig = &orig_beam_elements[ be_index++ ]; ptr_srot = ::st_SRotation_add( eb, ::st_SRotation_get_angle( ptr_orig ) ); ASSERT_TRUE( ptr_srot != nullptr ); ASSERT_TRUE( ::st_Buffer_get_num_of_objects( eb ) == be_index ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( ptr_srot ) - ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_cos_angle( ptr_srot ) - ::st_SRotation_get_cos_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_sin_angle( ptr_srot ) - ::st_SRotation_get_sin_angle( ptr_orig ) ) ); } /* --------------------------------------------------------------------- */ ASSERT_TRUE( ::st_Buffer_get_size( eb ) > size_t{ 0 } ); std::vector< raw_t > data_buffer( ::st_Buffer_get_size( eb ), raw_t{ 0 } ); data_buffer.assign( ::st_Buffer_get_const_data_begin( eb ), ::st_Buffer_get_const_data_end( eb ) ); ::st_Buffer cmp_buffer; ::st_Buffer_preset( &cmp_buffer ); int success = ::st_Buffer_init( &cmp_buffer, data_buffer.data(), data_buffer.size() ); ASSERT_TRUE( success == 0 ); ASSERT_TRUE( ::st_Buffer_get_num_of_objects( eb ) == ::st_Buffer_get_num_of_objects( &cmp_buffer ) ); object_t const* obj_it = ::st_Buffer_get_const_objects_begin( eb ); object_t const* obj_end = ::st_Buffer_get_const_objects_end( eb ); object_t const* cmp_it = ::st_Buffer_get_const_objects_begin( &cmp_buffer ); be_index = size_t{ 0 }; for( ; obj_it != obj_end ; ++obj_it, ++cmp_it ) { ptr_orig = &orig_beam_elements[ be_index++ ]; ASSERT_TRUE( ::st_Object_get_type_id( obj_it ) == BEAM_ELEMENT_TYPE_ID ); ASSERT_TRUE( ::st_Object_get_type_id( obj_it ) == ::st_Object_get_type_id( cmp_it ) ); ASSERT_TRUE( ::st_Object_get_size( obj_it ) >= sizeof( belem_t ) ); ASSERT_TRUE( ::st_Object_get_size( obj_it ) == ::st_Object_get_size( cmp_it ) ); belem_t const* elem = reinterpret_cast< belem_t const* >( ::st_Object_get_const_begin_ptr( obj_it ) ); belem_t const* cmp_elem = reinterpret_cast< belem_t const* >( ::st_Object_get_const_begin_ptr( cmp_it ) ); ASSERT_TRUE( ptr_orig != elem ); ASSERT_TRUE( ptr_orig != cmp_elem ); ASSERT_TRUE( elem != nullptr ); ASSERT_TRUE( cmp_elem != nullptr ); ASSERT_TRUE( cmp_elem != elem ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( elem ) - ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_cos_angle( elem ) - ::st_SRotation_get_cos_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_sin_angle( elem ) - ::st_SRotation_get_sin_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_angle( cmp_elem ) - ::st_SRotation_get_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_cos_angle( cmp_elem ) - ::st_SRotation_get_cos_angle( ptr_orig ) ) ); ASSERT_TRUE( EPS > std::fabs( ::st_SRotation_get_sin_angle( cmp_elem ) - ::st_SRotation_get_sin_angle( ptr_orig ) ) ); } /* --------------------------------------------------------------------- */ ::st_Buffer_delete( eb ); ::st_Buffer_free( &cmp_buffer ); }
size_t poisson_square(tkernel<glm::tvec2<T, P>> & kernel, const T min_dist, const unsigned int num_probes) { assert(kernel.depth() == 1); std::random_device RD; std::mt19937_64 generator(RD()); std::uniform_real_distribution<> radius_dist(min_dist, min_dist * 2.0); std::uniform_real_distribution<> angle_dist(0.0, 2.0 * glm::pi<T>()); std::uniform_int_distribution<> int_distribute(0, std::numeric_limits<int>::max()); auto occupancy = poisson_square_map<T, P>{ min_dist }; size_t k = 0; // number of valid/final points within the kernel kernel[k] = glm::tvec2<T, P>(0.5, 0.5); auto actives = std::list<size_t>(); actives.push_back(k); occupancy.mask(kernel[k], k); while (!actives.empty() && k < kernel.size() - 1) { // randomly pick an active point const auto pick = int_distribute(generator); auto pick_it = actives.begin(); std::advance(pick_it, pick % actives.size()); const auto active = kernel[*pick_it]; std::vector<std::tuple<glm::tvec2<T, P>, T>> probes{ num_probes }; #pragma omp parallel for for (int i = 0; i < static_cast<int>(num_probes); ++i) { const auto r = radius_dist(generator); const auto a = angle_dist(generator); auto probe = glm::tvec2<T, P>{ active.x + r * cos(a), active.y + r * sin(a) }; // within square? (tilable) if (probe.x < 0.0) probe.x += 1.0; else if (probe.x >= 1.0) probe.x -= 1.0; if (probe.y < 0.0) probe.y += 1.0; else if (probe.y >= 1.0) probe.y -= 1.0; // Note: do NOT make this optimization //if (!tilable && (probe.x < 0.0 || probe.x > 1.0 || probe.y < 0.0 || probe.y > 1.0)) // continue; // points within min_dist? const auto masked = occupancy.masked(probe, kernel); const auto delta = glm::abs(active - probe); probes[i] = std::make_tuple<glm::tvec2<T, P>, T>(std::move(probe), (masked ? static_cast<T>(-1.0) : glm::dot(delta, delta))); } // pick nearest probe from sample set glm::vec2 nearest_probe; auto nearest_dist = 4 * min_dist * min_dist; auto nearest_found = false; for (int i = 0; i < static_cast<int>(num_probes); ++i) { // is this nearest point yet? - optimized by using square distance -> skipping sqrt const auto new_dist = std::get<1>(probes[i]); if (new_dist < 0.0 || nearest_dist < new_dist) continue; if (!nearest_found) nearest_found = true; nearest_dist = new_dist; nearest_probe = std::get<0>(probes[i]); } if (!nearest_found && (actives.size() > 0 || k > 1)) { actives.erase(pick_it); continue; } kernel[++k] = nearest_probe; actives.push_back(k); occupancy.mask(nearest_probe, k); } return k + 1; }