private static Affine GetCenteringTransformVisualCenter(IVertexSource vertexSource, double goalRadius) { var outsidePolygons = new List <List <IntPoint> >(); // remove all holes from the polygons so we only center the major outlines var polygons = vertexSource.CreatePolygons(); foreach (var polygon in polygons) { if (polygon.GetWindingDirection() == 1) { outsidePolygons.Add(polygon); } } IVertexSource outsideSource = outsidePolygons.CreateVertexStorage(); Vector2 center = outsideSource.GetWeightedCenter(); outsideSource = new VertexSourceApplyTransform(outsideSource, Affine.NewTranslation(-center)); double radius = MaxXyDistFromCenter(outsideSource); double scale = goalRadius / radius; var scalling = Affine.NewScaling(scale); var centering = Affine.NewTranslation(-center); return(centering * scalling); }
private Matrix4X4 GetCenteringTransformVisualCenter(IEnumerable <IObject3D> items, double goalRadius) { IEnumerable <(Vector2, Vector2, Vector2)> GetPolygons() { foreach (var item in items) { foreach (var meshItem in item.VisibleMeshes()) { var worldMatrix = meshItem.WorldMatrix(this); var faces = meshItem.Mesh.Faces; var vertices = meshItem.Mesh.Vertices; foreach (var face in faces) { if (face.normal.TransformNormal(worldMatrix).Z > 0) { yield return( new Vector2(vertices[face.v0].Transform(worldMatrix)), new Vector2(vertices[face.v1].Transform(worldMatrix)), new Vector2(vertices[face.v2].Transform(worldMatrix)) ); } } } } } var outsidePolygons = new List <List <IntPoint> >(); var projection = new Polygons(); // remove all holes from the polygons so we only center the major outlines var polygons = OrthographicZProjection.GetClipperPolygons(GetPolygons()); foreach (var polygon in polygons) { if (polygon.GetWindingDirection() == 1) { outsidePolygons.Add(polygon); } } IVertexSource outsideSource = outsidePolygons.CreateVertexStorage(); Vector2 center = outsideSource.GetWeightedCenter(); outsideSource = new VertexSourceApplyTransform(outsideSource, Affine.NewTranslation(-center)); double radius = MaxXyDistFromCenter(outsideSource); double scale = goalRadius / radius; var scalling = Matrix4X4.CreateScale(scale, scale, 1); var centering = Matrix4X4.CreateTranslation(-center.X, -center.Y, 0); return(centering * scalling); }
private Polygon GetBoundingCircle(Polygons basePolygons) { IntPoint center; double radius; if (Centering == CenteringTypes.Bounds) { IEnumerable <Vector2> GetVertices() { foreach (var polygon in basePolygons) { foreach (var positon in polygon) { yield return(new Vector2(positon.X, positon.Y)); } } } var circle = SmallestEnclosingCircle.MakeCircle(GetVertices()); center = new IntPoint(circle.Center.X, circle.Center.Y); radius = (long)circle.Radius; } else { var outsidePolygons = new List <List <IntPoint> >(); // remove all holes from the polygons so we only center the major outlines var polygons = VertexSource.CreatePolygons(); foreach (var polygon in polygons) { if (polygon.GetWindingDirection() == 1) { outsidePolygons.Add(polygon); } } IVertexSource outsideSource = outsidePolygons.CreateVertexStorage(); var polyCenter = outsideSource.GetWeightedCenter(); center = new IntPoint(polyCenter.X * 1000, polyCenter.Y * 1000); radius = 0; foreach (Polygon polygon in basePolygons) { foreach (IntPoint point in polygon) { long length = (point - center).Length(); if (length > radius) { radius = length; } } } } var boundingCircle = new Polygon(); int numPoints = 100; for (int i = 0; i < numPoints; i++) { double angle = i / 100.0 * Math.PI * 2.0; IntPoint newPointOnCircle = new IntPoint(Math.Cos(angle) * radius, Math.Sin(angle) * radius) + center; boundingCircle.Add(newPointOnCircle); } return(boundingCircle); }