// フツーのk-NN search。 void locate_irradiance_points(IrradianceCache::ResultIrradianceQueue* pqueue, KDTreeNode* node, IrradianceQuery &query) { if (node == NULL) return; const int axis = node->axis; double delta; switch (axis) { case 0: delta = query.search_position.x - node->point->position.x; break; case 1: delta = query.search_position.y - node->point->position.y; break; case 2: delta = query.search_position.z - node->point->position.z; break; } const Vec dir = node->point->position - query.search_position; const double distance2 = dir.LengthSquared(); const double dt = Dot(query.normal, dir / sqrt(distance2)); // イラディアンスキャッシュの重み const double weight = 1.0 / ((query.search_position - node->point->position).Length() / node->point->R0 + sqrt(1.0 - Dot(query.normal, node->point->normal))); if (weight > query.threashold) { pqueue->push(ElementForIrradianceQueue(node->point, weight)); } if (delta > 0.0) { // みぎ locate_irradiance_points(pqueue, node->right, query); if (delta * delta < query.max_distance2) { locate_irradiance_points(pqueue, node->left, query); } } else { // ひだり locate_irradiance_points(pqueue,node->left, query); if (delta * delta < query.max_distance2) { locate_irradiance_points(pqueue, node->right, query); } } }
inline const double intersect(const Ray &ray) { const double t = Dot(p0 - ray.org, normal) / Dot(ray.dir, normal); if (t <= EPS) return 0.0; Vec p = ray.org + t * ray.dir; Vec d = p - p0; const double ddota = Dot(d, a); if (ddota < 0.0 || ddota > a.LengthSquared()) return 0.0; const double ddotb = Dot(d, b); if (ddotb < 0.0 || ddotb > b.LengthSquared()) return 0.0; return t; }
// フツーのk-NN search。 void locate_points(typename KDTree<T>::ResultQueue* pqueue, KDTreeNode* node, typename KDTree<T>::Query &query) { if (node == NULL) return; const int axis = node->axis; double delta; switch (axis) { case 0: delta = query.search_position.x - node->point->position.x; break; case 1: delta = query.search_position.y - node->point->position.y; break; case 2: delta = query.search_position.z - node->point->position.z; break; } // 対象点<->探索中心の距離が設定半径以下 かつ 対象点<->探索中心の法線方向の距離が一定以下 という条件ならその対象点格納 const Vec dir = node->point->position - query.search_position; const double distance2 = dir.LengthSquared(); const double dt = Dot(query.normal, dir / sqrt(distance2)); if (distance2 < query.max_distance2 && fabs(dt) <= query.max_distance2 * 0.01) { pqueue->push(ElementForQueue(node->point, distance2)); if (pqueue->size() > query.max_search_num) { pqueue->pop(); query.max_distance2 = pqueue->top().distance2; } } if (delta > 0.0) { // みぎ locate_points(pqueue,node->right, query); if (delta * delta < query.max_distance2) { locate_points(pqueue, node->left, query); } } else { // ひだり locate_points(pqueue,node->left, query); if (delta * delta < query.max_distance2) { locate_points(pqueue, node->right, query); } } }