index 2d11b74190226f6d6361cc0fae4e450267eb0418..5b6d36c493776fbbec4e4231dd592a29c45433e8 100644 (file)
*
*/
-#include "convex-cover.h"
+#include <2geom/convex-cover.h>
#include <algorithm>
#include <map>
/** Todo:
void
ConvexHull::graham_scan() {
unsigned stac = 2;
- for(int i = 2; i < boundary.size(); i++) {
+ for(unsigned int i = 2; i < boundary.size(); i++) {
double o = SignedTriangleArea(boundary[stac-2],
boundary[stac-1],
boundary[i]);
void
ConvexHull::graham() {
+ if(is_degenerate()) // nothing to do
+ return;
find_pivot();
angle_sort();
graham_scan();
*/
bool
ConvexHull::no_colinear_points() const {
-
+ // XXX: implement me!
}
bool
map<int, int> abridges;
map<int, int> bbridges;
- for(int ia = 0; ia < a.boundary.size(); ia++) {
- for(int ib = 0; ib < b.boundary.size(); ib++) {
+ for(unsigned ia = 0; ia < a.boundary.size(); ia++) {
+ for(unsigned ib = 0; ib < b.boundary.size(); ib++) {
Point d = b[ib] - a[ia];
Geom::Coord e = cross(d, a[ia - 1] - a[ia]), f = cross(d, a[ia + 1] - a[ia]);
Geom::Coord g = cross(d, b[ib - 1] - a[ia]), h = cross(d, b[ib + 1] - a[ia]);
ConvexHull sweepline_intersection(ConvexHull const &a, ConvexHull const &b) {
ConvexHull ret;
- int al = 0;
- int bl = 0;
+ unsigned al = 0;
+ unsigned bl = 0;
while(al+1 < a.boundary.size() &&
(a.boundary[al+1][Y] > b.boundary[bl][Y])) {
bl++;
}
// al and bl now point to the top of the first pair of edges that overlap in y value
- double sweep_y = std::min(a.boundary[al][Y],
- b.boundary[bl][Y]);
+ //double sweep_y = std::min(a.boundary[al][Y],
+ // b.boundary[bl][Y]);
+ return ret;
}
/*** ConvexHull intersection(ConvexHull a, ConvexHull b);
* (Proof: take any two points both in a and in b. Any point between them is in a by convexity,
* and in b by convexity, thus in both. Need to prove still finite bounds.)
*/
-ConvexHull intersection(ConvexHull a, ConvexHull b) {
+ConvexHull intersection(ConvexHull /*a*/, ConvexHull /*b*/) {
ConvexHull ret;
+ /*
int ai = 0, bi = 0;
int aj = a.boundary.size() - 1;
int bj = b.boundary.size() - 1;
-
+ */
/*while (true) {
if(a[ai]
}*/
ab[-1] = 0;
bb[-1] = 0;
- int i = -1;
+ int i = -1; // XXX: i is int but refers to vector indices
if(a.boundary[0][1] > b.boundary[0][1]) goto start_b;
while(true) {
for(; ab.count(i) == 0; i++) {
ret.boundary.push_back(a[i]);
- if(i >= a.boundary.size()) return ret;
+ if(i >= (int)a.boundary.size()) return ret;
}
if(ab[i] == 0 && i != -1) break;
i = ab[i];
for(; bb.count(i) == 0; i++) {
ret.boundary.push_back(b[i]);
- if(i >= b.boundary.size()) return ret;
+ if(i >= (int)b.boundary.size()) return ret;
}
if(bb[i] == 0 && i != -1) break;
i = bb[i];
}
}*/
+double ConvexHull::centroid_and_area(Geom::Point& centroid) const {
+ const unsigned n = boundary.size();
+ if (n < 2)
+ return 0;
+ if(n < 3) {
+ centroid = (boundary[0] + boundary[1])/2;
+ return 0;
+ }
+ Geom::Point centroid_tmp(0,0);
+ double atmp = 0;
+ for (unsigned i = n-1, j = 0; j < n; i = j, j++) {
+ const double ai = -cross(boundary[j], boundary[i]);
+ atmp += ai;
+ centroid_tmp += (boundary[j] + boundary[i])*ai; // first moment.
+ }
+ if (atmp != 0) {
+ centroid = centroid_tmp / (3 * atmp);
+ }
+ return atmp / 2;
+}
+
+// TODO: This can be made lg(n) using golden section/fibonacci search three starting points, say 0,
+// n/2, n-1 construct a new point, say (n/2 + n)/2 throw away the furthest boundary point iterate
+// until interval is a single value
+Point const * ConvexHull::furthest(Point direction) const {
+ Point const * p = &boundary[0];
+ double d = dot(*p, direction);
+ for(unsigned i = 1; i < boundary.size(); i++) {
+ double dd = dot(boundary[i], direction);
+ if(d < dd) {
+ p = &boundary[i];
+ d = dd;
+ }
+ }
+ return p;
+}
+
+
+// returns (a, (b,c)), three points which define the narrowest diameter of the hull as the pair of
+// lines going through b,c, and through a, parallel to b,c TODO: This can be made linear time by
+// moving point tc incrementally from the previous value (it can only move in one direction). It
+// is currently n*O(furthest)
+double ConvexHull::narrowest_diameter(Point &a, Point &b, Point &c) {
+ Point tb = boundary.back();
+ double d = INFINITY;
+ for(unsigned i = 0; i < boundary.size(); i++) {
+ Point tc = boundary[i];
+ Point n = -rot90(tb-tc);
+ Point ta = *furthest(n);
+ double td = dot(n, ta-tb)/dot(n,n);
+ if(td < d) {
+ a = ta;
+ b = tb;
+ c = tc;
+ d = td;
+ }
+ tb = tc;
+ }
+ return d;
+}
};