乱序的线不断取中点连接, 最终收敛成椭圆

13 篇文章 0 订阅

先说做法:

随机生成一些点,
用线段连接这些点,
再取各条线段的中点,
再用线段连接这些点,
再取各条线段的中点,
再用线段连接这些点,

最后会收敛于椭圆


再上图:在这里插入图片描述

上代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PointsToOval : MonoBehaviour
{
    const int posCount = 10;

    LineRenderer lineRender;

    List<Transform> allPoints;
    List<Vector3> oldPoss;
    List<Vector3> newPoss;

    void Start()
    {
        lineRender = gameObject.AddComponent<LineRenderer>();
        lineRender.startWidth = 0.1f;
        lineRender.endWidth = 0.1f;
        lineRender.loop = true;
        lineRender.numCapVertices = 0; //设置一个大于0的数, 可使首尾2点的边角更圆滑, 见图1
        lineRender.numCornerVertices = 0; //设置一个大于0的数, 可使连接点的边角更圆滑, 见图2
        lineRender.positionCount = posCount; //这里是个坑, 如果不设置positionCount, 就只能传入2个点

        allPoints = new List<Transform>();
        oldPoss = new List<Vector3>();
        newPoss = new List<Vector3>();

        CreateAllPoints();
        ResetAllPoints();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.R))
        {
            ResetAllPoints();
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            DivideAllPoints();
        }
        if (Input.GetKey(KeyCode.Space))
        {
            DivideAllPoints();
        }
    }

    void CreateAllPoints()
    {
        for (int i = 0; i < posCount; i++)
        {
            Transform point = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
            point.localScale = Vector3.one * 0.1f;
            allPoints.Add(point);
        }
    }

    void ResetAllPoints()
    {
        oldPoss.Clear();
        for (int i = 0; i < posCount; i++)
        {
            float x = Random.Range(-5f, 5f);
            float y = Random.Range(-5f, 5f);
            Vector3 randomPos = new Vector3(x, y, 0);
            oldPoss.Add(randomPos);

            allPoints[i].position = randomPos;
        }
        lineRender.SetPositions(oldPoss.ToArray());
    }

    void DivideAllPoints()
    {
        newPoss.Clear();
        for (int i = 0, cnt = oldPoss.Count; i < cnt; i++)
        {
            Vector3 linkPos;
            if (i == 0)
            {
                linkPos = oldPoss[cnt - 1];
            }
            else
            {
                linkPos = oldPoss[i - 1];
            }
            Vector3 newPos = (oldPoss[i] + linkPos) / 2;
            newPoss.Add(newPos);

            allPoints[i].position = newPos;
        }
        lineRender.SetPositions(newPoss.ToArray());

        oldPoss.Clear();
        //此处要深拷贝, newPoss = oldPoss是不行的
        newPoss.ForEach(p => oldPoss.Add(p));
    }
}

顺便复习下LineRender
lineRender.numCapVertices = 0; //设置一个大于0的数, 可使首尾2点的边角更圆滑, 见图1:
在这里插入图片描述
lineRender.numCornerVertices = 0; //设置一个大于0的数, 可使连接点的边角更圆滑, 见图2:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值