LoginSignup
0
0

More than 1 year has passed since last update.

対称性のあるmeshを作る

Last updated at Posted at 2021-09-11

はじめに

Unityでスクリプトからmeshを作って 対称性のあるオブジェクトを描画しようとしてみた備忘録

環境:Unity 2020.3.12f1

対称なものをつくる

Quaternionであらかじめ
軸に対して対称となる回転系を用意しておく。

これに、中心から少し離れた位置にある座標を掛けることで、球面上のどこかの点をとるようになる。

うまく内側の球と外側の球の大きさや角度を調整すると
多面体や星形多面体などの対称性のある形が現れるはず。

流れ

まず一つ 
三角ポリゴンを描画し、
前後にミラーし、
上下にミラーし、

あと、X軸、Y軸に90度づつねじれた形に回転しつつ複製しています。

スクリプト

MakePolyhedron.cs
using System.Collections.Generic;
using UnityEngine;

public class MakePolyhedron : MonoBehaviour
{
    //  3軸対象
    readonly Quaternion[] _qs3S = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 90, 90), Quaternion.Euler(90, 0, 90)};

    //  前後対象
    readonly Quaternion[] _qfbs = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 180, 0)};

    //  上下対象
    readonly Quaternion[] _qtbts = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 0, 180)};

    private readonly List<Vector3> _vertices = new List<Vector3>();

    private Mesh _mesh;

    private void Start()
    {
        GetComponent<Renderer>().material.SetColor("_Color",
            new Color(Random.Range(0.25f, 0.85f), Random.Range(0.25f, 0.85f), Random.Range(0.25f, 0.85f)));

        _mesh = new Mesh();

        TriangleSetUp();

        var meshFilter = GetComponent<MeshFilter>();
        meshFilter.mesh = _mesh;
    }

    private void TriangleSetUp()
    {
        foreach (var qs3 in _qs3S)
        {
            foreach (var qfb in _qfbs)
            {
                foreach (var qtbt in _qtbts)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        //  頂点を用意
                        _vertices.Add(Quaternion.Euler(Random.Range(0, 45), Random.Range(0, 45), Random.Range(0, 45)) *
                                      new Vector3(0, 1, 0));
                    }
                }
            }
        }

        //  頂点登録
        _mesh.SetVertices(_vertices);

        var triangles = new List<int>();

        for (int i = 0; i < _vertices.Count; i++)
        {
            triangles.Add(i);
        }

        _mesh.SetTriangles(triangles, 0);
    }


    private void Update()
    {
        TriangleSeed(1 + Mathf.Sin(Time.timeSinceLevelLoad), 1, 45 + Mathf.Sin(Time.timeSinceLevelLoad) * 45);
        _mesh.SetVertices(_vertices);
        _mesh.RecalculateBounds();
        _mesh.RecalculateNormals();
    }

    private void TriangleSeed(float l1, float l2, float fa)
    {
        var id = 0;

        foreach (var qs3 in _qs3S)
        {
            foreach (var qfb in _qfbs)
            {
                foreach (var qtbt in _qtbts)
                {
                    //  頂点を用意
                    _vertices[id++] = qtbt * qfb * qs3 * Quaternion.Euler(0, 0, 0) * new Vector3(0, l1, 0);
                    _vertices[id++] = qtbt * qfb * qs3 * Quaternion.Euler(90, fa, 0) * new Vector3(0, l2, 0);
                    _vertices[id++] = qtbt * qfb * qs3 * Quaternion.Euler(90, -fa, 0) * new Vector3(0, l2, 0);
                }
            }
        }
    }
}

Mesh描画のためのコンポーネント

image.png

MeshFilterとMeshRenererが必要なようです。

ちょっと複製の仕方を変えてみる

    //  前後対象 -> 4回回転対称
    readonly Quaternion[] _qfbs = {Quaternion.Euler(0, 0, 0), Quaternion.Euler(0, 90, 0), Quaternion.Euler(0, 180, 0), Quaternion.Euler(0, 270, 0)};
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0