anchor.diff:                y = -1.0;
                 break;
             }
  -          segments[segment * 2] = x * radius;
  -          segments[segment * 2 + 1] = y * radius;
  +          break;
  +        case 2:
  +          var segmentMod = segment + 15 * segmentsPerTunnelSegment ~/ 16;
  +          var i = segmentMod ~/ (segmentsPerTunnelSegment ~/ 3);
  +          var j = segmentMod % (segmentsPerTunnelSegment ~/ 3);
  +          final angle = -PI / 6 + 2 * PI * i / 3;
  +          final nextAngle = -PI / 6 + 2 * PI * (i + 1) / 3;
  +          x = cos(angle) +
  +              ((cos(nextAngle) - cos(angle)) *
  +                  (j / (segmentsPerTunnelSegment ~/ 3)));
  +          y = sin(angle) +
  +              ((sin(nextAngle) - sin(angle)) *
  +                  (j / (segmentsPerTunnelSegment ~/ 3)));
  +          break;
         }
  +      segments[segment * 2] = x * radius[segment % 2];
  +      segments[segment * 2 + 1] = y * radius[segment % 2];
       }
   
       return segments;
  
positive.code:     var obstacleList =
          new List.generate(9, (index) => index < obstacles ? true : false);
      obstacleList.shuffle(random);
      for (int i = -2; i < 3; i++) {
        for (int j = -2; j < 3; j++) {
          var obstacleType = isBorder(i, j)
              ? -1
              : obstacleList.removeLast() ? random.nextInt(shapes) : -1;
  
negative.code:   final double tunnelLength = 500.0;
    int segmentsPerTunnelSegment = 64 * 2;
    int lastSegmentType = 0;
    final int segmentTypes = 3;
  
    @override
    void processSystem() {
  