Esempio n. 1
0
/**
 * \return The best angle for fitting the convex hull to an axis aligned bounding box.
 *
 * Intended to be used with #BLI_convexhull_2d
 *
 * \param points  Orded hull points
 * (result of #BLI_convexhull_2d mapped to a contiguous array).
 *
 * \note we could return the index of the best edge too if its needed.
 */
float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n)
{
	unsigned int i, i_prev;
	float area_best = FLT_MAX;
	float angle_best = 0.0f;

	i_prev = n - 1;
	for (i = 0; i < n; i++) {
		const float *ev_a = points_hull[i];
		const float *ev_b = points_hull[i_prev];
		float dvec[2];

		sub_v2_v2v2(dvec, ev_a, ev_b);
		if (normalize_v2(dvec) != 0.0f) {
			float mat[2][2];
			float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};

			unsigned int j;
			const float angle = atan2f(dvec[0], dvec[1]);
			float area;

			angle_to_mat2(mat, angle);

			for (j = 0; j < n; j++) {
				float tvec[2];
				mul_v2_m2v2(tvec, mat, points_hull[j]);

				min[0] = min_ff(min[0], tvec[0]);
				min[1] = min_ff(min[1], tvec[1]);

				max[0] = max_ff(max[0], tvec[0]);
				max[1] = max_ff(max[1], tvec[1]);

				area = (max[0] - min[0]) * (max[1] - min[1]);
				if (area > area_best) {
					break;
				}
			}

			if (area < area_best) {
				area_best = area;
				angle_best = angle;
			}
		}

		i_prev = i;
	}

	return angle_best;
}
Esempio n. 2
0
static void edit_text_cache_populate_select(void *vedata, Object *ob)
{
  EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl;
  const Curve *cu = ob->data;
  EditFont *ef = cu->editfont;
  float final_mat[4][4], box[4][2];
  struct GPUBatch *geom = DRW_cache_quad_get();

  for (int i = 0; i < ef->selboxes_len; i++) {
    EditFontSelBox *sb = &ef->selboxes[i];

    float selboxw;
    if (i + 1 != ef->selboxes_len) {
      if (ef->selboxes[i + 1].y == sb->y) {
        selboxw = ef->selboxes[i + 1].x - sb->x;
      }
      else {
        selboxw = sb->w;
      }
    }
    else {
      selboxw = sb->w;
    }
    /* NOTE: v2_quad_corners_to_mat4 don't need the 3rd corner. */
    if (sb->rot == 0.0f) {
      copy_v2_fl2(box[0], sb->x, sb->y);
      copy_v2_fl2(box[1], sb->x + selboxw, sb->y);
      copy_v2_fl2(box[3], sb->x, sb->y + sb->h);
    }
    else {
      float mat[2][2];
      angle_to_mat2(mat, sb->rot);
      copy_v2_fl2(box[0], sb->x, sb->y);
      mul_v2_v2fl(box[1], mat[0], selboxw);
      add_v2_v2(box[1], &sb->x);
      mul_v2_v2fl(box[3], mat[1], sb->h);
      add_v2_v2(box[3], &sb->x);
    }
    v2_quad_corners_to_mat4(box, final_mat);
    mul_m4_m4m4(final_mat, ob->obmat, final_mat);

    DRW_shgroup_call_obmat(stl->g_data->overlay_select_shgrp, geom, final_mat);
  }
}