Example #1
0
 public RiverNode(Garden garden, RiverNode parent, Point3i location, RiverNode child) {
   super(garden, 0, parent, location, 1, GardenCategory.CATEGORY_WATER);
   parent.child = this;
   this.child = child;
   crossSectionalArea = parent.crossSectionalArea;
   //        System.out.println("Connecting tributary to another river @ " + location);
 }
Example #2
0
 private void addCrossSectionalArea(RiverNode node, int crossSectionalArea) {
   Set<RiverNode> processedNodes = new HashSet<RiverNode>();
   while (node != null) {
     if (processedNodes.contains(node)) {
       logger.severe("Loop in river!");
       return;
     } else {
       processedNodes.add(node);
     }
     node.crossSectionalArea += crossSectionalArea;
     drawLine(
         node.parent.location,
         node.location,
         (int) Math.round(Math.sqrt(node.crossSectionalArea)),
         false,
         category);
     node = node.child;
   }
 }
Example #3
0
  @Override
  protected boolean sprout() {
    boolean endRiver = child != null;
    if (garden.isWater(location.x, location.y)) {
      // There is already water here; end the river here
      // TODO: grow lake?
      endRiver = true;
    }

    if (parent != null) {
      drawLine(
          parent.location,
          location,
          (int) Math.round(Math.sqrt(crossSectionalArea)),
          false,
          category);
    }

    if (endRiver) {
      return (parent != null);
    }

    // Find coordinates of lowest point on a surrounding circle
    // Midpoint circle ("Bresenham's") algorithm
    final boolean[] lowerPointFound = new boolean[1];
    final int[] lowestHeightCoords = new int[2];
    int radius = 0;
    for (int r = 3; (!lowerPointFound[0]) && (r <= 9); r += 2) {
      radius = r;
      final float[] lowestHeight = {garden.getHeight(location.x, location.y)};
      GeometryUtil.visitCircle(
          r,
          new GeometryVisitor() {
            @Override
            public boolean visit(int dx, int dy, float d) {
              float height = garden.getHeight(location.x + dx, location.y + dy);
              if (height < lowestHeight[0]) {
                lowestHeight[0] = height;
                lowestHeightCoords[0] = location.x + dx;
                lowestHeightCoords[1] = location.y + dy;
                lowerPointFound[0] = true;
              }
              return true;
            }
          });
    }

    if (lowerPointFound[0]) {
      // Find existing nodes to connect with (not belonging to the same
      // river)
      List<RiverNode> nearbyNodes =
          garden.findSeeds(RiverNode.class, lowestHeightCoords[0], lowestHeightCoords[1], radius);
      int ownNodesEncountered = 0;
      for (RiverNode riverNode : nearbyNodes) {
        if (riverNode.getOrigin() == getOrigin()) {
          // Another node of same river
          ownNodesEncountered++;
          if (ownNodesEncountered < 2) {
            continue;
          } else {
            // We seem to be circing the drain. Abort! Abort!
            return true;
          }
        }
        if (riverNode.child != null) {
          garden.plantSeed(new RiverNode(garden, this, riverNode.location, riverNode.child));
          addCrossSectionalArea(riverNode.child, crossSectionalArea);
        } else {
          garden.plantSeed(new RiverNode(garden, this, riverNode.location));
        }
        return true;
      }

      garden.plantSeed(
          new RiverNode(
              garden, this, new Point3i(lowestHeightCoords[0], lowestHeightCoords[1], -1)));
      return true;
    } else {
      // No lower point around; end the river here
      // TODO: start a lake?
      return (parent != null);
    }
  }
Example #4
0
 public RiverNode(Garden garden, RiverNode parent, Point3i location) {
   super(garden, 0, parent, location, 1, GardenCategory.CATEGORY_WATER);
   parent.child = this;
   crossSectionalArea = parent.crossSectionalArea;
   //        System.out.println("Extending river to " + location);
 }