/// <summary> /// Non destructive join of two rectangles. /// </summary> /// <param name="a">first joined rectangle /// </param> /// <param name="b">second joined rectangle /// </param> /// <returns>rectangle containing cover of these two rectangles /// </returns> public static RectangleRn Join(RectangleRn a, RectangleRn b) { RectangleRn r = new RectangleRn(a); r.Join(b); return(r); }
public RectangleRn WrappingRectangle() { Line line = new Line(points[0], points[1]); RectangleRn wr = line.WrappingRectangle(); for (int i = 1; i < points.Length; i++) { line = new Line(points[i], points[(i + 1) % points.Length]); wr.Join(line.WrappingRectangle()); } return(wr); }
/// <summary> /// Non destructive join of two rectangles. /// </summary> /// <param name="a">first joined rectangle /// </param> /// <param name="b">second joined rectangle /// </param> /// <returns>rectangle containing cover of these two rectangles /// </returns> public static RectangleRn Join(RectangleRn a, RectangleRn b) { RectangleRn r = new RectangleRn(a); r.Join(b); return r; }
internal RectangleRn cover() { RectangleRn r = new RectangleRn(b[0]); for (int i = 1; i < n; i++) { r.Join(b[i]); } return r; }
RtreeRnPage splitPage(Storage storage, RectangleRn r, object obj) { int i, j, seed0 = 0, seed1 = 0; double[] rectArea = new double[card+1]; double waste; double worstWaste = Double.MinValue; // // As the seeds for the two groups, find two rectangles which waste // the most area if covered by a single rectangle. // rectArea[0] = r.Area(); for (i = 0; i < card; i++) { rectArea[i+1] = b[i].Area(); } RectangleRn bp = r; for (i = 0; i < card; i++) { for (j = i+1; j <= card; j++) { waste = RectangleRn.JoinArea(bp, b[j-1]) - rectArea[i] - rectArea[j]; if (waste > worstWaste) { worstWaste = waste; seed0 = i; seed1 = j; } } bp = b[i]; } byte[] taken = new byte[card]; RectangleRn group0, group1; double groupArea0, groupArea1; int groupCard0, groupCard1; RtreeRnPage pg; taken[seed1-1] = 2; group1 = new RectangleRn(b[seed1-1]); if (seed0 == 0) { group0 = new RectangleRn(r); pg = new RtreeRnPage(storage, obj, r); } else { group0 = new RectangleRn(b[seed0-1]); pg = new RtreeRnPage(storage, branch.GetRaw(seed0-1), group0); setBranch(seed0-1, r, obj); } groupCard0 = groupCard1 = 1; groupArea0 = rectArea[seed0]; groupArea1 = rectArea[seed1]; // // Split remaining rectangles between two groups. // The one chosen is the one with the greatest difference in area // expansion depending on which group - the rect most strongly // attracted to one group and repelled from the other. // while (groupCard0 + groupCard1 < card + 1 && groupCard0 < card + 1 - card/2 && groupCard1 < card + 1 - card/2) { int betterGroup = -1, chosen = -1; double biggestDiff = -1; for (i = 0; i < card; i++) { if (taken[i] == 0) { double diff = (RectangleRn.JoinArea(group0, b[i]) - groupArea0) - (RectangleRn.JoinArea(group1, b[i]) - groupArea1); if (diff > biggestDiff || -diff > biggestDiff) { chosen = i; if (diff < 0) { betterGroup = 0; biggestDiff = -diff; } else { betterGroup = 1; biggestDiff = diff; } } } } Debug.Assert(chosen >= 0); if (betterGroup == 0) { group0.Join(b[chosen]); groupArea0 = group0.Area(); taken[chosen] = 1; pg.setBranch(groupCard0++, b[chosen], branch.GetRaw(chosen)); } else { groupCard1 += 1; group1.Join(b[chosen]); groupArea1 = group1.Area(); taken[chosen] = 2; } } // // If one group gets too full, then remaining rectangle are // split between two groups in such way to balance cards of two groups. // if (groupCard0 + groupCard1 < card + 1) { for (i = 0; i < card; i++) { if (taken[i] == 0) { if (groupCard0 >= groupCard1) { taken[i] = 2; groupCard1 += 1; } else { taken[i] = 1; pg.setBranch(groupCard0++, b[i], branch.GetRaw(i)); } } } } pg.n = groupCard0; n = groupCard1; for (i = 0, j = 0; i < groupCard1; j++) { if (taken[j] == 2) { setBranch(i++, b[j], branch.GetRaw(j)); } } // truncate rest of link branch.Length = groupCard1; branch.Length = card; return pg; }