using UnityEngine; public class Polymer2 : MonoBehaviour { public float length=5f; public int n=200; float l; public Vector3 r0 = new Vector3(0f, 0f, 0f); public Vector3[] chain; public float[] mass; public float[] k; public Vector3[] v0; public Vector3[] v; public Vector3[] f0; public Vector3[] a; Vector3[] prev; public float vmax = 0.3f; public float springk = 80f; public float dt; public GameObject[] atoms; float time = 0; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { time = 0; l = length/n; chain = new Vector3[n+2]; Vector3 prev0 = Vector3.zero; for (int i = 1; i < n+1; i++) { chain[i] = prev0 + new Vector3(l, 0f, 0f); prev0 = chain[i]; } chain[0] = chain[1]; chain[n + 1] = chain[n]; mass = new float[n + 2]; for (int i = 0; i < n + 2; i++) { mass[i] = 1f; } //mass[n] = 10000f; // mass[n+1] = 10000f; k = new float[n + 2]; for (int i = 0; i < n + 2; i++) { k[i] = springk; } v0 = new Vector3[n + 2]; v = new Vector3[n + 2]; f0 = new Vector3[n + 2]; a = new Vector3[n + 2]; prev = new Vector3[n + 2]; atoms = new GameObject[n + 0]; dt = Time.deltaTime; // dt = 1f / 20f; for (int i = 1; i < n + 1; i++) { atoms[i-1] = GameObject.CreatePrimitive(PrimitiveType.Sphere); atoms[i - 1].GetComponent().enabled = false; if (i%2==0) { atoms[i - 1].GetComponent().material.SetColor("_Color", Color.red); } else { atoms[i - 1].GetComponent().material.SetColor("_Color", Color.green); } atoms[i - 1].transform.localScale = new Vector3(l / 0.5f, l / 0.5f, l /0.5f); atoms[i - 1].transform.position = chain[i]; } } // Update is called once per frame void FixedUpdate() { Vector3[] dr; dr = differences(chain); for (int i = 1; i < n + 1; i++) { a[i] = ( (k[i]*fdr(-dr[i-1])) + (k[i] * fdr(dr[i])) + f(time)[i])/mass[i]; } a[0] = a[1]; a[n + 1] = a[n]; for (int i = 0; i < n + 2; i++) { v[i] = a[i]*dt + prev[i]; } // for (int i = 1; i < n + 1; i++) { if (v[i].magnitude > vmax) { v[i].Normalize(); v[i] *= vmax; } } for (int i = 0; i < n + 2; i++) { if (v[i].magnitude > vmax) { v[i].Normalize(); v[i] *= vmax; } } for (int i = 0; i < n + 2; i++) { prev[i] = v[i]; } for (int i = 0; i < n + 2; i++) { chain[i] += v[i] * dt; } for (int i = 1; i < n + 1; i++) { atoms[i - 1].transform.position = chain[i]; } } Vector3[ ] f(float t) { Vector3[] impulse = new Vector3[n + 2]; // for (int i = 0; i < n + 2; i++) { impulse[i] = new Vector3 (Random.Range(-1f,1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)); } for (int i = 0; i < n + 2; i++){ impulse[i] = Random.onUnitSphere; } return impulse; } Vector3 fdr(Vector3 direction) { Vector3 dr = Vector3.zero; if (direction.magnitude < l) { dr = -1f * direction; } else if (direction.magnitude == l) { dr = Vector3.zero; } else if (direction.magnitude > l) { dr = direction; } return dr; } Vector3[] differences(Vector3[] list) { Vector3[] vectors = new Vector3[n + 1]; for (int i = 1; i < n + 2; i++) { vectors[i-1] = list[i]-list[i-1]; } return vectors; } }