/**
 * Find the most distant point between the 2 knots.
 */
static uint knot_find_split_point(
        const struct PointData *pd,
        const struct Knot *knot_l, const struct Knot *knot_r,
        const uint knots_len,
        const uint dims)
{
	uint split_point = SPLIT_POINT_INVALID;
	double split_point_dist_best = -DBL_MAX;

	const double *offset = &pd->points[knot_l->index * dims];

#ifdef USE_VLA
	double v_plane[dims];
	double v_proj[dims];
	double v_offset[dims];
#else
	double *v_plane =   alloca(sizeof(double) * dims);
	double *v_proj =    alloca(sizeof(double) * dims);
	double *v_offset =  alloca(sizeof(double) * dims);
#endif

	sub_vn_vnvn(
	        v_plane,
	        &pd->points[knot_l->index * dims],
	        &pd->points[knot_r->index * dims],
	        dims);

	normalize_vn(v_plane, dims);

	const uint knots_end = knots_len - 1;
	const struct Knot *k_step = knot_l;
	do {
		if (k_step->index != knots_end) {
			k_step += 1;
		}
		else {
			/* wrap around */
			k_step = k_step - knots_end;
		}

		if (k_step != knot_r) {
			sub_vn_vnvn(v_offset, &pd->points[k_step->index * dims], offset, dims);
			project_plane_vn_vnvn_normalized(v_proj, v_offset, v_plane, dims);

			double split_point_dist_test = len_squared_vn(v_proj, dims);
			if (split_point_dist_test > split_point_dist_best) {
				split_point_dist_best = split_point_dist_test;
				split_point = k_step->index;
			}
		}
		else {
			break;
		}

	} while (true);

	return split_point;
}
Exemple #2
0
float normalize_vn_vn(float *array_tar, const float *array_src, const int size)
{
	double d = len_squared_vn(array_src, size);
	float d_sqrt;
	if (d > 1.0e-35) {
		d_sqrt = (float)sqrt(d);
		mul_vn_vn_fl(array_tar, array_src, size, 1.0f / d_sqrt);
	}
	else {
		fill_vn_fl(array_tar, size, 0.0f);
		d_sqrt = 0.0f;
	}
	return d_sqrt;
}