我想我已经解决了这个问题,这要感谢一位朋友。我会在这里发布我现在正在做的事情,以防有人好奇。
简而言之,从中心开始算出六边形的顶点,然后将六边形的每个边细分为i
个位置,其中i
是层数。 / p>
我使用SkiaSharp用C#绘制了它,但是代码对语言而言并没有什么特别之处,没有理由不能用任何语言编写该代码。这是重要的位:
const float seedAngle = (float)(Math.PI / 3.0);
static void SeedOfLifeDemo(int x,int y) {
//setting up Skia stuff,this will be different depending what language you're using.
var info = new SKImageInfo(x,y);
using var bitmap = FlatImage(info,SKColors.White);
SKCanvas canvas = new SKCanvas(bitmap);
float radius = Math.Min(x,y) / 15;
SKPoint center = new SKPoint(x / 2f,y / 2f);
SKPaint strokePaint = new SKPaint {
Color = SKColors.Black,Style = SKPaintStyle.Stroke,StrokeWidth = 1,IsAntialias = true,};
int layers = 4;
//Draw the very central circle. This is just a little easier than adding that edge case to SubdividedHexagonAboutPoint
canvas.DrawCircle(center,radius,strokePaint);
for (int i = 1; i <= layers; i++) {
foreach (SKPoint p in SubdividedHexagonAboutPoint(center,radius * i,i)) {
canvas.DrawCircle(p,strokePaint);
}
}
SaveImage(bitmap,"SeedOfLifeFastDemo.Jpg");//More Skia specific stuff
}
//The magic!
static List<SKPoint> SubdividedHexagonAboutPoint(SKPoint centre,float radius,int subdivisions) {
List<SKPoint> points = new List<SKPoint>(6 * subdivisions);
SKPoint? prevPoint = null;
for (int i = 0; i < 7; i++) {//Step around the circle. The 7th step is to close the last edge
float x = (float)(Math.Sin(seedAngle * i) * radius + centre.X);
float y = (float)(Math.Cos(seedAngle * i) * radius + centre.Y);
SKPoint point = new SKPoint(x,y);
if (prevPoint != null) {
points.Add(point);//include the "primary" 6 points
if (subdivisions > 0) {
float xDist = (point.X - prevPoint.Value.X) / subdivisions;
float yDist = (point.Y - prevPoint.Value.Y) / subdivisions;
for (int sub = 1; sub < subdivisions; sub++) {
SKPoint subPoint = new SKPoint(point.X - xDist * sub,point.Y - yDist * sub);
points.Add(subPoint);//include the edge subdivisions
}
}
}
prevPoint = point;
}
return points;
}
这确实是一个非常有趣的练习,这是递归使用不当会真正咬住你的另一个例子。
本文链接:https://www.f2er.com/3118118.html