Skip to content

Instantly share code, notes, and snippets.

@kazukitanaka0611
Created December 3, 2021 01:07
Show Gist options
  • Save kazukitanaka0611/4b8eb4dd25f6983a152d981dc58cec8e to your computer and use it in GitHub Desktop.
Save kazukitanaka0611/4b8eb4dd25f6983a152d981dc58cec8e to your computer and use it in GitHub Desktop.
3角形から8角形までのフラクタルをLineRenderで描くコード(AnimationCurveのtime,valueを利用)
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class KochLine : MonoBehaviour
{
[SerializeField]
[Range(0, 5)]
private int _index = 0;
[SerializeField]
private AnimationCurve _curve = null;
[SerializeField]
private float[] _generators;
private readonly int[] PointsNumbers = { 3, 4, 5, 6, 7, 8 };
private readonly Vector3 RotateAxis = new Vector3(0.0f, 0.0f, 1.0f);
private LineRenderer _lineRenderer = null;
private Vector3[] _sourcePositions;
private Vector3[] _targetPositions;
private void Awake()
{
CreateLine();
}
private void CreateLine()
{
int initiatorPointsAmount = PointsNumbers[_index];
Vector3 rotateVector = new Vector3(1.0f, 0.0f, 0.0f);
rotateVector = Quaternion.AngleAxis(0.0f, RotateAxis) * rotateVector;
_sourcePositions = new Vector3[initiatorPointsAmount + 1];
for (var i = 0; i < initiatorPointsAmount; i++)
{
_sourcePositions[i] = rotateVector;
rotateVector = Quaternion.AngleAxis(360.0f / initiatorPointsAmount, RotateAxis) * rotateVector;
}
_sourcePositions[initiatorPointsAmount] = _sourcePositions[0];
_targetPositions = _sourcePositions;
for (var i = 0; i < _generators.Length; i++)
{
CreateKoch(_targetPositions, _generators[i]);
}
if (TryGetComponent<LineRenderer>(out _lineRenderer))
{
_lineRenderer.enabled = true;
_lineRenderer.useWorldSpace = false;
_lineRenderer.loop = true;
_lineRenderer.positionCount = _sourcePositions.Length;
_lineRenderer.SetPositions(_sourcePositions);
}
}
private void CreateKoch(Vector3[] positions, float generatorMultiplier)
{
Keyframe[] keys = _curve.keys;
float precisionMultiplier = Mathf.Pow(10.0f, 2.0f);
Quaternion rotation = Quaternion.AngleAxis(-90f, RotateAxis);
int max = ((positions.Length - 1) * (keys.Length - 1)) + 1;
Vector3[] newPos = new Vector3[max];
Vector3[] targetPos = new Vector3[max];
int index = 0;
for (int i = 0; i < positions.Length - 1; i++)
{
Vector3 startPosition = positions[i];
Vector3 endPosition = positions[i + 1];
float length = (endPosition - startPosition).magnitude;
Vector3 direction = (endPosition - startPosition) / length;
newPos[index] = startPosition;
targetPos[index] = startPosition;
for (var j = 1; j < keys.Length - 1; j++)
{
float time = Mathf.Round(keys[j].time * precisionMultiplier) / precisionMultiplier;
float value = Mathf.Round(keys[j].value * precisionMultiplier) / precisionMultiplier;
float moveAmount = length * time;
float heightAmount = value * generatorMultiplier;
Vector3 movePos = startPosition + direction * moveAmount;
Vector3 heightDir = rotation * direction;
newPos[index + j] = movePos;
targetPos[index + j] = (movePos + heightDir * heightAmount);
}
index += (keys.Length - 1);
}
newPos[max - 1] = positions[0];
targetPos[max - 1] = positions[0];
_sourcePositions = newPos;
_targetPositions = targetPos;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment