Farseer physics body generation from voronoi cells
This commit is contained in:
@@ -200,7 +200,7 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "generatelevel":
|
case "generatelevel":
|
||||||
Game1.Level = new Level(Game1.localRandom.Next(), 20, 5000, 5000);
|
Game1.Level = new Level(Game1.localRandom.Next(), 20, 500, 500);
|
||||||
break;
|
break;
|
||||||
case "fowenabled":
|
case "fowenabled":
|
||||||
case "fow":
|
case "fow":
|
||||||
|
|||||||
+36
-28
@@ -41,7 +41,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
for (int i = 0; i<2; i++)
|
for (int i = 0; i<2; i++)
|
||||||
{
|
{
|
||||||
int site = (i==0) ? ge.site1 : ge.site2;
|
Site site = (i==0) ? ge.site1 : ge.site2;
|
||||||
VoronoiCell cell = cells.Find(c => c.site == site);
|
VoronoiCell cell = cells.Find(c => c.site == site);
|
||||||
if (cell == null)
|
if (cell == null)
|
||||||
{
|
{
|
||||||
@@ -60,11 +60,11 @@ namespace Subsurface
|
|||||||
List<Vector2> vlist = new List<Vector2>();
|
List<Vector2> vlist = new List<Vector2>();
|
||||||
foreach (GraphEdge ge in cell.edges)
|
foreach (GraphEdge ge in cell.edges)
|
||||||
{
|
{
|
||||||
if (vlist.Contains(ge.point1)) continue;
|
if (!vlist.Contains(ge.point1)) vlist.Add(ge.point1);
|
||||||
vlist.Add(ge.point1);
|
if (!vlist.Contains(ge.point2)) vlist.Add(ge.point2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vlist.Count < 2) continue;
|
if (vlist.Count < 3) continue;
|
||||||
|
|
||||||
for (int i = 0; i < vlist.Count; i++ )
|
for (int i = 0; i < vlist.Count; i++ )
|
||||||
{
|
{
|
||||||
@@ -74,7 +74,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
//get farseer 'vertices' from vectors
|
//get farseer 'vertices' from vectors
|
||||||
Vertices _shapevertices = new Vertices(vlist);
|
Vertices _shapevertices = new Vertices(vlist);
|
||||||
//_shapevertices.Sort(less);
|
_shapevertices.Sort(new CompareCCW(cell.Center));
|
||||||
|
|
||||||
//feed vertices array to BodyFactory.CreatePolygon to get a new farseer polygonal body
|
//feed vertices array to BodyFactory.CreatePolygon to get a new farseer polygonal body
|
||||||
Body _newBody = BodyFactory.CreatePolygon(Game1.world, _shapevertices, 15);
|
Body _newBody = BodyFactory.CreatePolygon(Game1.world, _shapevertices, 15);
|
||||||
@@ -85,29 +85,6 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int Compare(Vector2 a, Vector2 b, Vector2 center)
|
|
||||||
{
|
|
||||||
if (a.X - center.X >= 0 && b.X - center.X < 0) return 1;
|
|
||||||
if (a.X - center.X < 0 && b.X - center.X >= 0) return -1;
|
|
||||||
if (a.X - center.X == 0 && b.X - center.X == 0)
|
|
||||||
{
|
|
||||||
if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(a.Y - b.Y);
|
|
||||||
return Math.Sign(b.Y-a.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute the cross product of vectors (center -> a) x (center -> b)
|
|
||||||
float det = (a.X - center.X) * (b.Y - center.Y) - (b.X - center.X) * (a.Y - center.Y);
|
|
||||||
if (det < 0) return 1;
|
|
||||||
if (det > 0) return -1;
|
|
||||||
|
|
||||||
// points a and b are on the same line from the center
|
|
||||||
// check which point is closer to the center
|
|
||||||
float d1 = (a.X - center.X) * (a.X - center.X) + (a.Y - center.Y) * (a.Y - center.Y);
|
|
||||||
float d2 = (b.X - center.X) * (b.X - center.X) + (b.Y - center.Y) * (b.Y - center.Y);
|
|
||||||
return Math.Sign(d1 - d2);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<GraphEdge> MakeVoronoiGraph(List<PointF> sites, Voronoi voronoi, int width, int height)
|
List<GraphEdge> MakeVoronoiGraph(List<PointF> sites, Voronoi voronoi, int width, int height)
|
||||||
{
|
{
|
||||||
double[] xVal = new double[sites.Count];
|
double[] xVal = new double[sites.Count];
|
||||||
@@ -132,4 +109,35 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CompareCCW : IComparer<Vector2>
|
||||||
|
{
|
||||||
|
private Vector2 center;
|
||||||
|
|
||||||
|
public CompareCCW(Vector2 center)
|
||||||
|
{
|
||||||
|
this.center = center;
|
||||||
|
}
|
||||||
|
public int Compare(Vector2 a, Vector2 b)
|
||||||
|
{
|
||||||
|
if (a.X - center.X >= 0 && b.X - center.X < 0) return 1;
|
||||||
|
if (a.X - center.X < 0 && b.X - center.X >= 0) return -1;
|
||||||
|
if (a.X - center.X == 0 && b.X - center.X == 0)
|
||||||
|
{
|
||||||
|
if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(a.Y - b.Y);
|
||||||
|
return Math.Sign(b.Y - a.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the cross product of vectors (center -> a) x (center -> b)
|
||||||
|
float det = (a.X - center.X) * (b.Y - center.Y) - (b.X - center.X) * (a.Y - center.Y);
|
||||||
|
if (det < 0) return 1;
|
||||||
|
if (det > 0) return -1;
|
||||||
|
|
||||||
|
// points a and b are on the same line from the center
|
||||||
|
// check which point is closer to the center
|
||||||
|
float d1 = (a.X - center.X) * (a.X - center.X) + (a.Y - center.Y) * (a.Y - center.Y);
|
||||||
|
float d2 = (b.X - center.X) * (b.X - center.X) + (b.Y - center.Y) * (b.Y - center.Y);
|
||||||
|
return Math.Sign(d1 - d2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -543,8 +543,8 @@ namespace Voronoi2
|
|||||||
newEdge.point1 = point1;
|
newEdge.point1 = point1;
|
||||||
newEdge.point2 = point2;
|
newEdge.point2 = point2;
|
||||||
|
|
||||||
newEdge.site1 = leftSite.sitenbr;
|
newEdge.site1 = leftSite;
|
||||||
newEdge.site2 = rightSite.sitenbr;
|
newEdge.site2 = rightSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clip_line( Edge e )
|
private void clip_line( Edge e )
|
||||||
|
|||||||
@@ -117,9 +117,14 @@ namespace Voronoi2
|
|||||||
public class VoronoiCell
|
public class VoronoiCell
|
||||||
{
|
{
|
||||||
public List<GraphEdge> edges;
|
public List<GraphEdge> edges;
|
||||||
public int site;
|
public Site site;
|
||||||
|
|
||||||
public VoronoiCell(int site)
|
public Vector2 Center
|
||||||
|
{
|
||||||
|
get { return new Vector2((float)site.coord.x, (float)site.coord.y); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public VoronoiCell(Site site)
|
||||||
{
|
{
|
||||||
edges = new List<GraphEdge>();
|
edges = new List<GraphEdge>();
|
||||||
this.site = site;
|
this.site = site;
|
||||||
@@ -129,7 +134,7 @@ namespace Voronoi2
|
|||||||
public class GraphEdge
|
public class GraphEdge
|
||||||
{
|
{
|
||||||
public Vector2 point1, point2;
|
public Vector2 point1, point2;
|
||||||
public int site1, site2;
|
public Site site1, site2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// للترتيب
|
// للترتيب
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user