I'm thinking of creating a program to let me play or solve slitherlink puzzles, like on krazydad.com. It consists of tiles of 4, 5, 6, 7 and 8 sides. All but the seven sided tiles seem to have sides with the same length, with the sides between two seven sided tiles (and therefore connecting five-sided tiles to 4 sided tiles) having sides of approximately 70% of the normal length. As you can see in the picture below, octagons are surrounded by alternating pentagons and hexagons. These are attached to others a by the far sides of the hexagons. Attached to the tips of the pentagons are smaller lines connecting to squares connecting to other groups. Around the squares are then formed seven-sided figures with two short sides. I think the outer edge is defined by just omitting tiles that are too far away from the center.
For a data structure I think I need a graph connecting all nodes. I can let the user click to place a solid line on the closest link, and I can check for loops or too many lines entering a node fairly easily. I'll also need to create tiles and associate lines to them, with inner lines being assigned to both tiles, but treated as one line.
As for setting it up, I am thinking of manually figuring out the points and defining the minimal set of repeated tiles (1 8, 4 5, 4 6, 4 7 and 1 4), then placing them next to each other. When placing, I would check for existing close points to each one I'm placing and combine them if found. Then I would need to check for duplicate lines and merge them as well.
Is there an easier or cleaner way to A) generate the tiling or B) merge the nodes and links when doing my tiling?
some observations that might help:
if you join the centres of neighbouring polygons you have a delaunay triangulation (1).
the dual (2) of the delaunay triangulation is the graph above (with slightly different edge lengths, but you can adjust that if necessary)
there's a discussion here (3) of how to generate graphs from delaunay triangulations
so, putting that together, you could:
generate the centres of the tiles (see below)
construct the delaunay triangulation from the tile centres (by joining neigbours).
find the dual to get the graph you want (the process of finding the dual should be supported by a good graph library)
to generate the pattern of tile centres, take the minimal set and start with the centre 8. for each 90 degree rotation about there, add the (rotated) minimal set (plus an 8 in addition to the one you're rotating around), removing duplicates. then do the same on the 8s that you have added (either recurse or use a stack).
once you have the centres, i'm not sure what the best way to connect neighbours would be - you want some efficient way of generating a set of candidates. but it's not a hard problem, just fiddly (a "fancy" solution would be quadtree or spatial hashes, but just a crude binning would probably be enough).
Related
I am currently developing an indoor path-finding. I have multiple floors and different rooms. How will I be able to implement a* algorithm in the images of each floor using c# wpf?
I use spatial A* for the game I'm working on.
Spatial A* uses movement "cost" to work out the best route between two points. The cost mentions is supplied by an array. Usually a 2d array of number - float uint or whatever.
Moving through a square/cell at position x,y thus costs the number in that 2d array. EG costs[2,3] would be the cost of movement through the cell 2 cells across from the left and 3 down from the top of an imaginary grid projected onto your "room".
If the move is diagonal then there's also a multiplier to consider but that will be in whichever implementation you go with.
Hence you need a 2d costed array per floor.
You would need to somehow analyse your pictures and work out an appropriate size for a costed cell. This should match the smallest size of a significant piece of terrain in your floor.
You would then translate your picture into a costed array. You've not told us anywhere near enough to tell you specifically how to do that. Maybe that would have to be a manual process though.
Blocked cells get the max number, empty cells get 1. Depending on your requirements that might be that. Or alternatively you might have actors leaping tables and chairs etc.
You give the pathing algorithm start and target location (x,y), the appropriate costed array and it works out the cheapest route.
I am trying to find a way to get the line (two points in 3D space) of the intersection between two rectangles.
I ran into this question: Intersection between two rectangles in 3D
But this is not my issue. In that question, the rectangle is treated as only the bounds (the perimeter), while I am looking for the rectangle as a whole (think about a picture frame vs the picture itself).
I've figured out that, in every case, there will either be an intersection line (two points), or no intersection at all. If the intersection was just on the borders, therefore just a point, it can be treated as no intersection in my case.
My scenario is that one of these rectangle represents a "static" surface, which cannot move or change. The other one represents a "dynamic" surface, which I have to adapt to avoid crossing
Example:
Once I obtain p1 and p2, which are points in the 3D space, my goal is to modify the Dynamic rectangle into a 3d polygon, which will no longer cross the static rectangle, like this:
So you can see why "edge intersections" are irrelevant to my situation. I am turning "real" intersections into edge intersections, so any edge intersection doesn't require me to do anything with it.
I am only looking for a formula, starting with two sets of 4 points (the rectangles), that would give me the two points of the line of their intersection, or would tell me that there is no (relevant) intersection.
Every formula I've found on this site or others doesn't fit my needs, or doesn't let me input arbitrary rectangles (for example, I can't fix my problem with a formula that uses planes or that treats a rectangle as simply 4 lines)
I am, of course, trying to code it (in C#), therefore any code answer is a great help, but I am confident that even a math-only answer would suffice for me to produce the code from it, therefore I will accept an answer that is only composed of pseudo-code or straight up mathematical formulas, provided they are either simple enough or explained well enough for me to understand what is happening.
If you are OK with just algorithm rather than full code here is a sketch:
Build 2 planes from the rectangles (any 3 points will do as in this answer)
Find the intersection line I of those 2 planes as in this answer or find out that the planes are parallel so there is no intersection
Find the intersections of the I line with the lines containing all sides of the rectangles as in this answer
Check whether some points found in the previous step lie inside the corresponding sides of the rectangles (line segments). This step potentially can be merged with the previous one, but I put it separately for simplicity. Now you potentially have 0, 1 or 2 segments that represent the intersections of the I line with your two rectangles (note that here point is treated as an edge case of a segment where both ends are the same). If you don't have 2 segments, there is no intersection of the rectangles.
Assuming at the previous step you found 2 segments (one in each rectangle) on the line I, you just need to find their intersection and it will be your answer (again, empty means no intersection).
I'm in the process of making a 2d, gridbased game and have reached a standstill due to challenging code. I need to navigate from one cell in the grid to another if possible, but with a maximum of 2 turns.
The red ball is the goal, and the green paths are ones that are valid, "turns" are highlighted by a blue circle.
Without brute forcing the issue and checking every posssible path how could this be done? I've experimented with a few ideas along with an a* implementation, but no luck so far. Any ideas, using unity's API or anything else is highly appreciated.
This can be solved using normal A* by creating a specially-designed directed weighted graph from your original grid.
The trick is to create a graph with multiple "layers". Layer 0 represents 0 turns having been made so far, layer 1 represents 1 turn made, and layer 2 is 2 turns. A node connects to its neighbors on the same layer if they can be reached without turning, and its neighbors on the next layer if they require a turn.
Hopefully this is enough information for you to create the graph, but if not, the explicit steps would be:
Create 6 copies of the graph, Layer_0_Horizontal, Layer_0_Vertical, Layer_1_Horizontal, Layer_1_Vertical, Layer_2_Horizontal, Layer_2_Vertical.
For each node in a Horizontal layer, remove its edges to its vertical neighbors, and replace them with edges to nodes in the next layer down, with eg. Layer_1_Vertical being below Layer_0_Horizontal. Edges in Layer_2 won't be replaced. Do the same thing for Vertical layers / horizontal edges.
Create a fake 'start' node, and connect it to the two Layer_0 nodes that represent that same grid-square with 0-weight edges. If your A* implementation only supports one goal-node, do the same with the goal.
If you want to prefer longer paths with less turns over shorter paths with more turns (is that even possible with only two turns??), give the edges between layers an extremely large weight.
I'd like to generate flat islands existing of multiple hexagons. So far I've been able to create hexagonal meshes with code, but can't figure out how to position them in groups, creating a randomly shaped island. (Any shape that's not a perfect circle, square etc.) I think I would need an algorithm, that places hexagon tiles next to multiple sides of an existing tile. If you can help me with an idea for an algorithm, then that would be great.
Are you looking for something like this?
Place 1 hexagon.
for i in (islandSize-1):
Scan all hexagons for open sides. Place open sides in a list named hexBorders
Choose a random index in hexBorders, attach a new hexagon there
That algorithm should give you a fairly roundish island, roughly centered on the original hex, because older hexes have more chances to get picked.
You can tune this shape by preferring either newer or older hexagons (e.g. you could include hexagon age in hexBorders, and adjust your random choice so it prefers younger hexes).
Recently I was also doing random map generator for tile based map and hit a wall while try to add more advanced features (in tile space) the realism of output was not good. I decided to create a 2D/3D image based map and then convert it to tile map. Still not finished with adding all the features I want but the result is already a magnitude better then before:
map generator
see my simple random map generator in C++. It is based on Diamond&Square algorithm with some tweaking to obtain island like maps.
conversion to tile-map
Simply map Cartesian pixel into your hexagonal grid layout. You can also compute the average of some area instead of using single pixel per cell/tile.
For 3D tile maps this will produce "voxel-ated" output so you need to add additional filtering see
How to procedurally generate tile map for some ideas.
Since is a pretty open ended question, this article by Red Blob Games about hexagonal data structures would be an excellent place to start. The author describes how you can use 2D arrays to store the hexagons, and how you can iterate through them.
Once you understand the relation of hexagons to one another you can start to iterate through them in interesting ways.
Probably the easiest way to generate an "island" would be with a SIR-type model, also known as an epidemic model. This is a model that is commonly used by researchers to simulate the spread of infectious disease, but I've found that you can also use it to generate pseudo-natural shapes (like an island!). SIR stands for Susceptible-Infectious-Recovered. Those are the three states of a "cell", or in this case hexagon. At any given step of the algorithm, an infected cell can infect a neighboring cell. Think about it like this: at the start of your algorithm, one hexagon is "infected" (land) and the rest are not (water). At each iteration of the algorithm, cells adjacent to an infected cell have a chance (say, 1 in 10) of being infected as well (turning into land). After many iterations, you'll find that the shape of the infected group of hexagons is pretty random looking, but they're all touching. For a grid-bsed example, here's some images I've uploaded to imgur. Pseudo-code for this algorithm is below.
cellsToDo = [originCell]
for 100 iterations:
for each cell in cellsToDo:
for each neighbor to the current cell:
if randomValueBetween(0, 10) == 1:
set the current cell as infected
add the current cell to the cellsToDo list
There are definitely other algorithms, but I'd start with learning how the hexagons are related to each other and can be stored.
Is there any simple (or not) algorithm that is capable of creating polygons from closed path?
Assume w have following path:
0,0; 2,0, 2,1; 1,1;
1,2; 2,2; 2,3; 0,3;
I need to be able to create polygon indexes for OpenGL vertex buffer. Language I'm using is C#.
Someone suggested me Convex Hull, but it's not the thing I'm looking for, cause I have a shape already. I know that this could be a trivial issue, but seriously, I can't find any description or something to point mi in the right direction.
Edit:
Answer 1 suggest to select a point and connect it to other not connected points, this works fine for presented in answer shape but it will not work for shape i posted, shape above looks like this:
Converting to triangles is either easy or hard, depending on what your requirements are and how well you want to do it.
If your polygon is convex, the easiest way is to use GL_TRIANGLES with the indicies
0, 1, 2, 0, 2, 3, 0, 3, 4, ...
It will look like this:
The situation for concave is more work. An algorithm that also works for concave polygons (not ones with holes!) is the Ear-clipping method, described on wikipedia (there is more on that page.)
Things get really interesting when you want a "good" triangulation: avoid skinny or small triangles, reduce number of triangles etc., and then you can trade off quality for speed. I won't go into any advanced algorithms here; searching for polygon triangulation on Google will get you lots of info.
As for normals, if your polygon is planar (it most likely "should" be) then take two non co-incident edges and cross product them (there are two normals and you probably only want one: you need to choose the order in which you cross product (clockwise or anticlockwise) based on the right hand rule.