Circle iterator now compensates for the matrix size and won't overflow.
This commit is contained in:
		
							parent
							
								
									35f2defc11
								
							
						
					
					
						commit
						857cd2f910
					
				
					 5 changed files with 25 additions and 23 deletions
				
			
		
							
								
								
									
										10
									
								
								lights.cpp
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								lights.cpp
									
										
									
									
									
								
							|  | @ -7,14 +7,10 @@ using std::vector; | |||
| namespace lighting { | ||||
| 
 | ||||
|   void LightRender::render_circle_light(LightSource source, Point at, PointList &has_light) { | ||||
|     for(matrix::circle it{at, source.distance + 1}; it.next();) { | ||||
|     for(matrix::circle it{$lightmap, at, source.distance + 1}; it.next();) { | ||||
|       for(int x = it.left; x < it.right; x++) { | ||||
|         if(matrix::inbounds($paths.$paths, x, it.y) && | ||||
|             $paths.$paths[it.y][x] != WALL_PATH_LIMIT) | ||||
|         { | ||||
|           $lightmap[it.y][x] = light_level(source.strength, x, it.y); | ||||
|           has_light.push_back({(size_t)x, (size_t)it.y}); | ||||
|         } | ||||
|         $lightmap[it.y][x] = light_level(source.strength, x, it.y); | ||||
|         has_light.push_back({(size_t)x, (size_t)it.y}); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
							
								
								
									
										15
									
								
								matrix.cpp
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								matrix.cpp
									
										
									
									
									
								
							|  | @ -180,21 +180,24 @@ namespace matrix { | |||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   circle::circle(Point center, int radius) : | ||||
|   circle::circle(Matrix &mat, Point center, int radius) : | ||||
|     center(center), radius(radius) | ||||
|   { | ||||
|     top = max(center.y - radius, size_t(0)); | ||||
|     bottom = center.y + radius; | ||||
|     width = matrix::width(mat); | ||||
|     height = matrix::height(mat); | ||||
|     top = max(int(center.y - radius), 0); | ||||
|     bottom = min(int(center.y + radius), height); | ||||
| 
 | ||||
|     y = top; | ||||
|   } | ||||
| 
 | ||||
|   bool circle::next() { | ||||
|     y++; | ||||
|     if(y <= bottom) { | ||||
|     if(y < bottom) { | ||||
|       dy = y - center.y; | ||||
|       dx = floor(sqrt(radius * radius - dy * dy)); | ||||
|       left = center.x - dx; | ||||
|       right = center.x + dx; | ||||
|       left = max(0, int(center.x - dx)); | ||||
|       right = min(width, int(center.x + dx)); | ||||
|       return true; | ||||
|     } else { | ||||
|       return false; | ||||
|  |  | |||
|  | @ -127,8 +127,10 @@ namespace matrix { | |||
|     int right = 0; | ||||
|     int top = 0; | ||||
|     int bottom = 0; | ||||
|     int width = 0; | ||||
|     int height = 0; | ||||
| 
 | ||||
|     circle(Point center, int radius); | ||||
|     circle(Matrix &mat, Point center, int radius); | ||||
|     void update(); | ||||
|     bool next(); | ||||
|   }; | ||||
|  |  | |||
|  | @ -226,7 +226,7 @@ TEST_CASE("prototype line algorithm", "[matrix:line]") { | |||
| } | ||||
| 
 | ||||
| TEST_CASE("prototype circle algorithm", "[matrix:circle]") { | ||||
|   for(int count = 0; count < 20; count++) { | ||||
|   for(int count = 0; count < 2000; count++) { | ||||
|     size_t width = Random::uniform<size_t>(10, 13); | ||||
|     size_t height = Random::uniform<size_t>(10, 15); | ||||
|     int pos_mod = Random::uniform<int>(-3,3); | ||||
|  | @ -238,12 +238,15 @@ TEST_CASE("prototype circle algorithm", "[matrix:circle]") { | |||
|       // use an empty map
 | ||||
|       Matrix result = map.walls(); | ||||
| 
 | ||||
|       for(matrix::circle it{start, radius}; it.next();) { | ||||
|       for(matrix::circle it{result, start, radius}; it.next();) { | ||||
|         for(int x = it.left; x < it.right; x++) { | ||||
|           // println("top={}, bottom={}, center.y={}, dy={}, left={}, right={}, x={}, y={}", it.top, it.bottom, it.center.y, it.dy, it.left, it.right, x, it.y);
 | ||||
|           if(matrix::inbounds(result, x, it.y)) { | ||||
|             result[it.y][x] += 1; | ||||
|           } | ||||
|           // println("RESULT {},{}", matrix::width(result), matrix::height(result));
 | ||||
|           REQUIRE(it.y >= 0); | ||||
|           REQUIRE(x >= 0); | ||||
|           REQUIRE(it.y < int(matrix::height(result))); | ||||
|           REQUIRE(x < int(matrix::width(result))); | ||||
|           result[it.y][x] += 1; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|  |  | |||
|  | @ -142,11 +142,9 @@ void WorldBuilder::generate() { | |||
|   $map.load_tiles(); | ||||
| 
 | ||||
|   Point center = $map.place_entity(1); | ||||
|   for(matrix::circle it{center, 3}; it.next();) { | ||||
|   for(matrix::circle it{$map.$walls, center, 3}; it.next();) { | ||||
|     for(int x = it.left; x < it.right; x++) { | ||||
|       if($map.inmap(x, it.y) && !$map.iswall(x, it.y)) { | ||||
|         $map.$tiles.set_tile(x, it.y, "WATER_TILE"); | ||||
|       } | ||||
|       $map.$tiles.set_tile(x, it.y, "WATER_TILE"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Zed A. Shaw
						Zed A. Shaw