Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 package edu.tum.cs.vis.model.util;
00010
00011 import java.awt.Color;
00012 import java.util.ArrayList;
00013 import java.util.List;
00014
00023 public class Region {
00024
00028 private final int id;
00029
00033 private float area;
00034
00042 private final float[] curvatureMinMax = new float[3];
00043
00047 private final List<Triangle> triangles = new ArrayList<Triangle>();
00048
00052 private final List<Triangle> boundaryTriangles = new ArrayList<Triangle>();
00053
00057 private final List<Region> regionNeighbors = new ArrayList<Region>();
00058
00062 private final List<Edge> edgeBoundary = new ArrayList<Edge>();
00063
00067 private float perimeter;
00068
00073 private Appearance appearance = new Appearance();
00074
00081 public Region(final int newId) {
00082 this.id = newId;
00083 this.initializeApperance();
00084 this.area = 0.0f;
00085 this.perimeter = 0.0f;
00086 this.curvatureMinMax[0] = this.curvatureMinMax[1] = this.curvatureMinMax[2] = 0.0f;
00087 }
00088
00098 public Region(final int newId, final Triangle initSeedTr) {
00099 this.id = newId;
00100 this.initializeApperance();
00101 this.area = 0.0f;
00102 this.perimeter = 0.0f;
00103 this.addTriangleToRegion(initSeedTr);
00104 this.curvatureMinMax[0] = initSeedTr.getCurvatureValues()[0];
00105 this.curvatureMinMax[1] = initSeedTr.getCurvatureValues()[1];
00106 this.curvatureMinMax[2] = initSeedTr.getCurvatureValues()[2];
00107 }
00108
00114 public int getRegionId() {
00115 return this.id;
00116 }
00117
00123 public float getAreaOfRegion() {
00124 return this.area;
00125 }
00126
00132 public Appearance getAppearance() {
00133 return this.appearance;
00134 }
00135
00141 public float getPerimeterOfRegion() {
00142 return this.perimeter;
00143 }
00144
00150 public List<Triangle> getTriangles() {
00151 return this.triangles;
00152 }
00153
00159 public List<Triangle> getBoundaryTriangles() {
00160 return this.boundaryTriangles;
00161 }
00162
00168 public List<Region> getNeighbors() {
00169 return this.regionNeighbors;
00170 }
00171
00177 public List<Edge> getBoundaryEdges() {
00178 return this.edgeBoundary;
00179 }
00180
00187 public float[] getCurvatureMinMaxOfRegion() {
00188 return this.curvatureMinMax;
00189 }
00190
00197 public List<Triangle> getOutsideBoundaryUnlabelled() {
00198 List<Triangle> unlabelledOutside = new ArrayList<Triangle>();
00199 for (int i = 0; i < boundaryTriangles.size(); ++i) {
00200 Triangle t = boundaryTriangles.get(i);
00201 for (Triangle n : t.getNeighbors()) {
00202 if (n.getRegionLabel() == -1) {
00203 unlabelledOutside.add(n);
00204 }
00205 }
00206 }
00207 return unlabelledOutside;
00208 }
00209
00217 public List<Edge> getCommonEdges(Region neighbor) {
00218 List<Edge> commonEdges = new ArrayList<Edge>();
00219 for (Edge e : this.edgeBoundary) {
00220 for (Edge en : neighbor.edgeBoundary) {
00221 if (e.isDirectNeighbor(en)) {
00222 commonEdges.add(e);
00223 break;
00224 }
00225 }
00226 }
00227 return commonEdges;
00228 }
00229
00238 public Edge getCommonEdge(Triangle triangle) {
00239 if (!boundaryTriangles.contains(triangle)) {
00240 for (Triangle n : boundaryTriangles) {
00241
00242 Edge edge = n.getCommonEdge(triangle);
00243 if (edge != null) {
00244 return edge;
00245 }
00246 }
00247 }
00248 return null;
00249 }
00250
00257 public void setApperance(final Appearance newAppearance) {
00258 this.appearance = newAppearance;
00259 }
00260
00267 public void setCurvatureMin(final float kMin) {
00268 this.curvatureMinMax[0] = kMin;
00269 }
00270
00277 public void setCurvatureMax(final float kMax) {
00278 this.curvatureMinMax[1] = kMax;
00279 }
00280
00287 public void setCurvatureMinMax(final float kMinkMax) {
00288 this.curvatureMinMax[2] = kMinkMax;
00289 }
00290
00299 public boolean isNeighbor(Region region) {
00300 if (regionNeighbors.contains(region)) {
00301 return true;
00302 }
00303 return false;
00304 }
00305
00310 public void initializeApperance() {
00311 int R, G, B, min = 0, max = 255;
00312 R = min + (int) (Math.random() * ((max - min) + 1));
00313 G = min + (int) (Math.random() * ((max - min) + 1));
00314 B = min + (int) (Math.random() * ((max - min) + 1));
00315 Color regionColor = new Color(R, G, B);
00316 this.appearance.setColorFill(regionColor);
00317 }
00318
00323 public void updateAreaOfRegion() {
00324 area = 0.0f;
00325 for (Triangle tr : triangles) {
00326 area += tr.getArea();
00327 }
00328 }
00329
00339 private void updateAreaOfRegion(final Triangle tr, final boolean toRemove) {
00340 if (tr != null) {
00341 if (toRemove == false) {
00342 area += tr.getArea();
00343 } else {
00344 area -= tr.getArea();
00345 }
00346 }
00347 }
00348
00352 public void updatePerimeterOfRegion() {
00353 perimeter = 0.0f;
00354 for (Edge e : edgeBoundary) {
00355 perimeter += e.getEdgeValue().length();
00356 }
00357 }
00358
00366 public void addTrianglesToRegion(final List<Triangle> newTr) {
00367 if (newTr != null) {
00368 for (int i = 0; i < newTr.size(); ++i) {
00369 if (newTr.get(i) != null) {
00370 Triangle triangle = newTr.get(i);
00371 if (!triangles.contains(triangle)) {
00372 triangles.add(triangle);
00373 triangle.setRegionLabel(id);
00374 triangle.appearance = this.appearance;
00375 this.updateAreaOfRegion(triangle, false);
00376 }
00377 }
00378 }
00379 }
00380 }
00381
00390 public void addTriangleToRegion(final Triangle newTr) {
00391 if (newTr != null && !triangles.contains(newTr) && newTr.getRegionLabel() == -1) {
00392 triangles.add(newTr);
00393 newTr.setRegionLabel(id);
00394 newTr.appearance = this.appearance;
00395 this.updateAreaOfRegion(newTr, false);
00396 this.addTriangleToRegionBoundary(newTr);
00397 }
00398 }
00399
00409 public void addTriangleToRegionBoundary(final Triangle newTr) {
00410 if (!triangles.containsAll(newTr.getNeighbors())) {
00411
00412 boundaryTriangles.add(newTr);
00413 } else {
00414
00415 for (Edge e : newTr.getEdges()) {
00416 List<Triangle> neighborsOfEdge = newTr.getNeighborsOfEdge(e);
00417 if (neighborsOfEdge.size() == 0) {
00418 boundaryTriangles.add(newTr);
00419 }
00420 }
00421 }
00422 List<Triangle> toRemove = new ArrayList<Triangle>();
00423
00424
00425 for (Triangle tr : newTr.getNeighbors()) {
00426
00427 boolean marginTriangle = false;
00428 for (Edge tre : tr.getEdges()) {
00429 List<Triangle> neighborsOfEdge = tr.getNeighborsOfEdge(tre);
00430 if (neighborsOfEdge.size() == 0) {
00431 marginTriangle = true;
00432 }
00433 }
00434
00435
00436 if (triangles.containsAll(tr.getNeighbors()) && !marginTriangle) {
00437 toRemove.add(tr);
00438 }
00439 }
00440
00441 boundaryTriangles.removeAll(toRemove);
00442 return;
00443 }
00444
00449 public void removeTriangleFromRegion(final Triangle toRemove) {
00450 if (triangles.remove(toRemove)) {
00451 updateAreaOfRegion(toRemove, true);
00452 if (boundaryTriangles.remove(toRemove)) {
00453 System.out.println("Triangle " + toRemove.toString()
00454 + " also removed from the boundary region");
00455 this.updateRegionBoundary();
00456 }
00457 }
00458
00459 toRemove.setRegionLabel(-1);
00460 }
00461
00465 public void updateRegionBoundary() {
00466 boundaryTriangles.clear();
00467 for (Triangle tr : triangles) {
00468 for (Edge e : tr.getEdges()) {
00469 List<Triangle> neighborsOfEdge = tr.getNeighborsOfEdge(e);
00470 if (neighborsOfEdge.size() == 0) {
00471 boundaryTriangles.add(tr);
00472 } else {
00473 for (int i = 0; i < neighborsOfEdge.size(); ++i) {
00474 if (triangles.contains(neighborsOfEdge.get(i))) {
00475 boundaryTriangles.add(tr);
00476 break;
00477 }
00478 }
00479 }
00480 }
00481 }
00482 }
00483
00491 public void updateRegionNeighbors(List<Region> allRegions) {
00492 regionNeighbors.clear();
00493 edgeBoundary.clear();
00494 for (Triangle t : boundaryTriangles) {
00495
00496 for (Edge e : t.getEdges()) {
00497 List<Triangle> neighborsOfEdge = t.getNeighborsOfEdge(e);
00498 if (neighborsOfEdge.size() != 0) {
00499 for (Triangle n : neighborsOfEdge) {
00500 if (n.getRegionLabel() != t.getRegionLabel()) {
00501 for (int i = 0; i < allRegions.size(); ++i) {
00502 if (allRegions.get(i).getRegionId() == n.getRegionLabel()
00503 && !regionNeighbors.contains(allRegions.get(i))) {
00504 regionNeighbors.add(allRegions.get(i));
00505 }
00506 if (!edgeBoundary.contains(e)) {
00507 edgeBoundary.add(e);
00508 }
00509 }
00510 }
00511 }
00512 } else {
00513 if (!edgeBoundary.contains(e)) {
00514 edgeBoundary.add(e);
00515 }
00516 }
00517 }
00518 }
00519 updatePerimeterOfRegion();
00520 }
00521
00538 public void buildUpRegion() {
00539 for (int i = 0; i < triangles.size(); ++i) {
00540 Triangle tr = triangles.get(i);
00541
00542 Edge[] edges = tr.getEdges();
00543 for (int j = 0; j < edges.length; ++j) {
00544 if (!edges[j].isSharpEdge()) {
00545 List<Triangle> neighborList = tr.getNeighborsOfEdge(edges[j]);
00546 if (neighborList.size() == 0) {
00547
00548
00549 continue;
00550 }
00551 for (Triangle neighbor : neighborList) {
00552 if (neighbor.getRegionLabel() != -1) {
00553
00554 continue;
00555 }
00556 Vertex oppositeVertex = neighbor.getOppositeVertexFromEdge(edges[j]);
00557 if (oppositeVertex != null
00558 && ((oppositeVertex.isSharpVertex()) || ((oppositeVertex
00559 .getClusterCurvatureVal()[0] == curvatureMinMax[0])
00560 && (oppositeVertex.getClusterCurvatureVal()[1] == curvatureMinMax[1]) && (oppositeVertex
00561 .getClusterCurvatureVal()[2] == curvatureMinMax[2])))) {
00562 this.addTriangleToRegion(neighbor);
00563 }
00564 }
00565 }
00566 }
00567 }
00568 }
00569
00570
00571
00572
00573
00574 @Override
00575 public String toString() {
00576 String print = "Region ID " + id + "\n";
00577 print = print + "Curvatures: KMin = " + curvatureMinMax[0] + ", KMax = "
00578 + curvatureMinMax[1] + ", KMinMax= " + curvatureMinMax[2] + "\n";
00579 print = print + "Triangles: " + triangles.size() + "\n";
00580 print = print + "Boundary Triangles: " + boundaryTriangles.size() + "\n";
00581 print = print + "Boundary Edges: " + edgeBoundary.size() + "\n";
00582 print = print + "Area: " + area + ", Perimeter: " + perimeter + "\n";
00583 return print;
00584 }
00585 }