Edo Kaal - SAM - Interactive
Edo Kael <edwinkaal00@gmail.com> | Thu, Jan 25, 2018 at 12:14 AM | |
To: "David W. Johnson" <dj@argos.vu>
Cc: James Sorensen <james@ecosleuth.com>
|
||
|
Re: suggestions regarding SAM simulations 1 message |
Edo Kael <edwinkaal00@gmail.com> | Mon, Jan 22, 2018 at 6:47 AM | |
To: "David W. Johnson" <dj@argos.vu>
Cc: James Sorensen <james@ecosleuth.com>
|
||
|
Re: suggestions regarding SAM simulations 1 message |
Edo Kael <edwinkaal00@gmail.com> | Sun, Jan 21, 2018 at 10:56 AM | |
To: "David W. Johnson" <dj@argos.vu>
|
||
|
From: MathPages - Min Energy Configuration
N=20: The equilibrium configuration of 20 charged particles on the surface of a sphere has a north and south pole. Below the north pole is an equilateral triangle of three particles. On the next lower level is another equilateral triangle of three particles, rotated by 60 degrees. On the next lower level, the equator, there are six particles, arranged in two equilateral triangles. These triangles are skewed, but not by 60 degrees. Then there are two more levels of equilateral triangles, and then the south pole. The configuration at each level is illustrated below. |
The separations have 26 distinct magnitudes, as summarized below: |
separation number example separation number example ---------- ------ ------- ---------- ------ -------- 0.8331592 12 (1,2) 0.7894919 12 (2,8) 1.8657231 6 (1,3) 1.4142136 12 (2,9) 1.2478910 6 (1,4) 1.3615374 12 (2,11) 1.4578665 12 (1,6) 1.8769439 12 (2,14) 1.3869718 3 (1,7) 1.9924151 3 (2,15) 0.8016163 12 (1,8) 1.7320508 6 (2,16) 0.7829612 6 (1,9) 0.8455036 3 (2,19) 1.8403727 6 (1,10) 0.9568466 6 (8,9) 1.4651562 12 (1,11) 1.7562587 6 (8,10) 1.5680184 6 (1,14) 1.8149394 6 (8,11) 1.7833875 12 (1,15) 1.4553299 6 (8,12) 1.9906722 6 (1,17) 1.0844446 3 (8,18) 1.1469114 3 (2,6) 2.0000000 1 (9,10)
Is it possible to make the electron ghostly as in can overlap with protons? and protons cannot overlap protons, electrons cannot overlap electrons Electrons and protons should be a small sphere an a larger sphere around it. The inner sphere is hard and the outer sphere is ghostly for the electrons, hard for the protons.
Then when overlap occurs between an electron and 2 protons, it should loose its attribute, meaning they annihilate. The only attraction should be between electron and proton, repelling between the similar that be interesting.....
Edo
On Fri, Jan 19, 2018 at 6:37 PM, Edo Kael <edwinkaal00@gmail.com> wrote:
David,
Been more or less thinking about what you are creating atm with the geometry and plus minus and have a few suggestions that may help a bit,- create a sphere around the protons (3 times the radius of the proton itself for example)- remove the center as an attracting force.....- Allow the protons and electron to be in the center, the center is only virtual!- create more groups of these yin yang structures (we call them nuclets) and see how that works out- make the repelling force (a little) for the electrons bigger then for the protonsmost fascinating the shape that appears with 20 spheres alone! am still kinda trying to find out what were looking at, it seems to be more or less geometrical, yet.... probably not a stable structure on its own, hence it does require the icosahedron, personally i am most pleased to see that 🙂--
using System.Collections; using System.Collections.Generic; using UnityEngine; using VRTK; using UnityEngine.UI; using ProceduralToolkit; public class Edo_Voronoi : MonoBehaviour { private Vector3 startPosition; public bool bPrint_Debug = false; public float proton_to_Proton = 500f; public float electron_to_Electron = 500f; [Range(0, 500f)] public float force_proton_to_Electron = 50f; public float like_to_like = 500f; public float opp_to_opp = 500f; public float centering_Mult = 1; private VRTK_InteractableObject vrtk_Interact_1; public GameObject preFab_Pos; public GameObject preFab_Neg; public GameObject proton_Prefab; public GameObject electron_Prefab; public GameObject instance_Location; public GameObject nucleus_Radius; [Range(-10, 10f)] public float restore_Coeff = 1f; [Range(0, 72f)] public float sphere_Radius = 21f; [Range(0, 20)] public float sa_Diameter; private float sa_Diameter_last; public Slider sld_Sphere_Radius; private GameObject[] positives = new GameObject[36]; private GameObject[] negatives = new GameObject[36]; private GameObject[] protons = new GameObject[3]; private GameObject[] electrons = new GameObject[3]; public Slider proton_sld; public Slider electron_sld; public Slider pos_sld; public Slider neg_sld; public enum MODE { FUNDAMENTALS, ORIGINAL_POS_NEG, }; private MODE mode = MODE.FUNDAMENTALS; public Button_VU bv_Upper_Mode; public Button_VU bv_Lower_Mode; public enum Handle_States { NORMAL, TOUCHED, GRABBED, } private Handle_States handle_State = Handle_States.NORMAL; public Color handle_Base_Col; public Color handle_Touched_Col; public Color handle_Grabbed_Col; private Color handle_Base_Emissive_Col; private VU_UI_MANAGER VU_UI; private ArgosMeshDraft aMD_Nucleus_Sphere; public AnimationCurve attractCurve; public AnimationCurve repelCurve; void Start() { Set_Force_Bezier_Knots(); startPosition = transform.position; aMD_Nucleus_Sphere = new ArgosMeshDraft(); OnMode_Button((int)MODE.FUNDAMENTALS); nucleus_Radius.transform.localScale = Vector3.one * sphere_Radius; vrtk_Interact_1 = GetComponent<VRTK_InteractableObject>(); VU_UI = VU_UI_MANAGER.Instance; vrtk_Interact_1.InteractableObjectTouched += new InteractableObjectEventHandler(DoObject_1_Touched); vrtk_Interact_1.InteractableObjectUntouched += new InteractableObjectEventHandler(DoObject_1_Untouched); vrtk_Interact_1.InteractableObjectGrabbed += new InteractableObjectEventHandler(DoObject_1_Grabbed); vrtk_Interact_1.InteractableObjectUngrabbed += new InteractableObjectEventHandler(DoObject_1_Ungrabbed); float dp = 10.61803f; Vector3 vDP = Vector3.one; Vector3 vNegStart = dp * Vector3.right; for (int i = 0; i < 36; i++) { positives[i] = Instantiate(preFab_Pos, instance_Location.transform.position + vDP, Quaternion.identity); negatives[i] = Instantiate(preFab_Neg, instance_Location.transform.position + vNegStart + vDP, Quaternion.identity); vDP += dp * Vector3.up + dp*Vector3.forward; if (i < 0) { positives[i].SetActive(true); negatives[i].SetActive(true); } else { positives[i].SetActive(false); negatives[i].SetActive(false); } } vDP = Vector3.one; for (int i = 0; i < 3; i++) { protons[i] = Instantiate(proton_Prefab, instance_Location.transform.position + vDP, Quaternion.identity); electrons[i] = Instantiate(electron_Prefab, instance_Location.transform.position + vNegStart + vDP, Quaternion.identity); vDP += dp * Vector3.up + dp * Vector3.forward; if (i < 1) { protons[i].SetActive(true); electrons[i].SetActive(true); } else { protons[i].SetActive(false); electrons[i].SetActive(false); } } aMD_Nucleus_Sphere.Add(MeshDraft.Sphere(1, 64, 64)); nucleus_Radius.GetComponent<MeshFilter>().mesh = aMD_Nucleus_Sphere.ToMeshInternal(); } private void DoObject_1_Touched(object sender, InteractableObjectEventArgs e) { handle_State = Handle_States.TOUCHED; VU_UI.Report_Touched(vrtk_Interact_1.gameObject, e.interactingObject); } private void DoObject_1_Untouched(object sender, InteractableObjectEventArgs e) { handle_State = Handle_States.NORMAL; VU_UI.Report_UnTouched(vrtk_Interact_1.gameObject, e.interactingObject); } private void DoObject_1_Grabbed(object sender, InteractableObjectEventArgs e) { handle_State = Handle_States.GRABBED; } private void DoObject_1_Ungrabbed(object sender, InteractableObjectEventArgs e) { handle_State = Handle_States.NORMAL; } private bool isValid_Vector(Vector3 v) { if (!float.IsNaN(v.x) && !float.IsNaN(v.y) && !float.IsNaN(v.z)) { return true; } else { return false; } } public void OnMode_Button(int i) { if(i==0) { bv_Upper_Mode.isON = true; bv_Lower_Mode.isON = false; mode = MODE.FUNDAMENTALS; } else if(i==1) { bv_Upper_Mode.isON = false; bv_Lower_Mode.isON = true; mode = MODE.ORIGINAL_POS_NEG; } } public void Set_Force_Bezier_Knots() { Keyframe[] ka = new Keyframe[4]; ka[0] = new Keyframe(0, -1f); ka[0].inTangent = 0; ka[1] = new Keyframe(sa_Diameter, 0); ka[1].inTangent = 0; ka[2] = new Keyframe(sa_Diameter * 2, 3); ka[2].inTangent = 0; ka[3] = new Keyframe(100f, 0.01f); ka[3].inTangent = 0; attractCurve = new AnimationCurve(ka); Keyframe[] kr = new Keyframe[2]; kr[0] = new Keyframe(0, 3); kr[0].inTangent = 0; kr[1] = new Keyframe(100f, 0.005f); kr[1].inTangent = 0; repelCurve = new AnimationCurve(kr); sa_Diameter_last = sa_Diameter; } public void On_PROTON_Slider() { int num_pos = (int)proton_sld.value; float dp = 10.61803f; Vector3 vDP = Vector3.one; Vector3 vNegStart = dp * Vector3.right; for (int i = 0; i < 3; i++) { if (i < num_pos) { protons[i].SetActive(true); protons[i].transform.position = instance_Location.transform.position + vDP; vDP += dp * Vector3.up + dp * Vector3.forward; } else { protons[i].SetActive(false); } } } public void On_ELECTRON_Slider() { int num_pos = (int)electron_sld.value; float dp = 10.61803f; Vector3 vDP = Vector3.one; Vector3 vNegStart = dp * Vector3.right; for (int i = 0; i < 3; i++) { if (i < num_pos) { electrons[i].SetActive(true); electrons[i].transform.position = instance_Location.transform.position + vDP; vDP += dp * Vector3.up + dp * Vector3.forward; } else { electrons[i].SetActive(false); } } } public void On_Pos_Slider() { int num_pos = (int)pos_sld.value; float dp = 10.61803f; Vector3 vDP = Vector3.one; Vector3 vNegStart = dp * Vector3.right; for (int i = 0; i<36; i++) { if (i < num_pos) { positives[i].SetActive(true); positives[i].transform.position = instance_Location.transform.position + vDP; vDP += dp * Vector3.up + dp * Vector3.forward; } else { positives[i].SetActive(false); } } } public void On_Neg_Slider() { int num_neg = (int)neg_sld.value; float dy = 0.1f; float dp = 10.61803f; Vector3 vDP = Vector3.one; Vector3 vNegStart = dp * Vector3.right; for (int i = 0; i < 36; i++) { if (i < num_neg) { negatives[i].SetActive(true); negatives[i].transform.position = instance_Location.transform.position +vNegStart + vDP; vDP += dp * Vector3.up + dp * Vector3.forward; } else { negatives[i].SetActive(false); } } } public void On_Radius_Nucleus_Slider() { sphere_Radius = sld_Sphere_Radius.value; nucleus_Radius.transform.localScale = Vector3.one * sphere_Radius; } public void On_Run_Button() { } public void Return_To_Start_Position() { transform.position = startPosition; } private void Original_POS_NEG_Fixed_Update() { //Distribute around sphere - Voronoi Action foreach (GameObject go in positives) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 vFrom; Vector3 vSum; Vector3 vRecip; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; rb.AddForce(amt * dist.normalized * restore_Coeff); foreach (GameObject gInner in positives) { if (gInner.activeSelf) { vSum = Vector3.zero; float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vRecip = (1f / r) * vFrom.normalized; vSum += vRecip; } if (isValid_Vector(vSum)) { rb.AddForce(like_to_like * vSum); } } } } } foreach (GameObject go in negatives) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 vFrom; Vector3 vSum; Vector3 vRecip; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; rb.AddForce(amt * dist.normalized * restore_Coeff); foreach (GameObject gInner in negatives) { if (gInner.activeSelf) { vSum = Vector3.zero; float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vRecip = (1f / r) * vFrom.normalized; vSum += vRecip; } if (isValid_Vector(vSum)) { rb.AddForce(like_to_like * vSum); } } } } } //Opposites foreach (GameObject go in positives) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 vFrom; Vector3 vSum; Vector3 vRecip; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; rb.AddForce(amt * dist.normalized * restore_Coeff); foreach (GameObject gInner in negatives) { if (gInner.activeSelf) { vSum = Vector3.zero; float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vRecip = (1f / r) * vFrom.normalized; vSum += vRecip; } if (isValid_Vector(vSum)) { rb.AddForce(-opp_to_opp * vSum); } } } } } foreach (GameObject go in negatives) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 vFrom; Vector3 vSum; Vector3 vRecip; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; rb.AddForce(amt * dist.normalized * restore_Coeff); foreach (GameObject gInner in positives) { if (gInner.activeSelf) { vSum = Vector3.zero; float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vRecip = (1f / r) * vFrom.normalized; vSum += vRecip; } if (isValid_Vector(vSum)) { rb.AddForce(-opp_to_opp * vSum); } } } } } } private void Fundamentals_Fixed_Update() { Vector3 vFrom; Vector3 vForceBase = Vector3.zero; if(sa_Diameter != sa_Diameter_last) { Set_Force_Bezier_Knots(); } //public float electron_to_Proton = 500f; foreach (GameObject go in protons) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; if (amt > 0) { rb.AddForce(amt * dist.normalized * restore_Coeff); } foreach (GameObject gInner in protons) { if (gInner.activeSelf) { float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vForceBase = repelCurve.Evaluate(r) * vFrom.normalized; //else if(r > sa_Diameter/2f) //{ // vForceBase = (1/sa_Diameter)*(0.625f*r/sa_Diameter + 0.375f) * vFrom.normalized; //} //else //{ // vForceBase = -(1 / sa_Diameter) * (0.625f * (sa_Diameter-r) / sa_Diameter + 0.375f) * vFrom.normalized; //} if (isValid_Vector(vForceBase)) { rb.AddForce(proton_to_Proton* vForceBase); } } } } } } foreach (GameObject go in electrons) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; if (amt > 0) { rb.AddForce(amt * dist.normalized * restore_Coeff); } foreach (GameObject gInner in electrons) { if (gInner.activeSelf) { float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vForceBase = repelCurve.Evaluate(r) * vFrom.normalized; if (isValid_Vector(vForceBase)) { rb.AddForce(electron_to_Electron * vForceBase); } } } } } } //Opposites foreach (GameObject go in protons) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; if (amt > 0) { rb.AddForce(amt * dist.normalized * restore_Coeff); } foreach (GameObject gInner in electrons) { if (gInner.activeSelf) { float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vForceBase = attractCurve.Evaluate(r) * vFrom.normalized; if (isValid_Vector(vForceBase)) { rb.AddForce(-force_proton_to_Electron * vForceBase); } } } } } } foreach (GameObject go in electrons) { if (go.activeSelf) { Rigidbody rb = go.GetComponent<Rigidbody>(); Rigidbody rbInner; Vector3 dist = transform.position - rb.position; float amt = dist.magnitude - sphere_Radius; if (amt > 0) { rb.AddForce(amt * dist.normalized * restore_Coeff); } foreach (GameObject gInner in protons) { if (gInner.activeSelf) { float r;//Radius from Neighbor if (go != gInner) { rbInner = gInner.GetComponent<Rigidbody>(); vFrom = rb.position - rbInner.position; r = vFrom.magnitude; vForceBase = attractCurve.Evaluate(r) * vFrom.normalized; if (isValid_Vector(vForceBase)) { rb.AddForce(-force_proton_to_Electron * vForceBase); } } } } } } } void FixedUpdate() { if(mode == MODE.ORIGINAL_POS_NEG) { Original_POS_NEG_Fixed_Update(); } else if(mode == MODE.FUNDAMENTALS) { Fundamentals_Fixed_Update(); } if (bPrint_Debug) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { //print("VN_[" + i.ToString() + "," + j.ToString() + "] points to " + vN_Points_to[i, j].ToString()); } } bPrint_Debug = false; } } Color curr_Color; Color curr_dot_Color; Color targ_Color; Color targ_dot_Color; float theta = 390; float target_theta = 0; public void Animate_Handle_Material()//UI HANDLE { return; curr_Color = Color.Lerp(curr_Color, targ_Color, Time.deltaTime * 1.61803f); curr_dot_Color = Color.Lerp(curr_dot_Color, targ_dot_Color, Time.deltaTime * 1.61803f); if (handle_State == Handle_States.NORMAL) { //target_theta = 300; targ_Color = handle_Base_Col; } else if (handle_State == Handle_States.TOUCHED) { //target_theta = 390; targ_Color = handle_Touched_Col; } else if (handle_State == Handle_States.GRABBED) { //target_theta = 570; targ_Color = handle_Grabbed_Col; } Renderer rend = GetComponent<Renderer>(); rend.material.SetColor("_Color", curr_Color); rend.material.SetColor("_EmissionColor", curr_Color); }
public void Update_Pair(GameObject proton, GameObject electron) { int curr_active = 0; bool found = false; for (int i = 0; i<12; i++) { if (neutron_pairs[i].active) { if (neutron_pairs[i].proton == proton && neutron_pairs[i].electron == electron) { curr_active = i; found = true; break; } } } if(!found) { bool bElectron_Paired = false; bool bProton_Paired = false; for(int i = 0; i<12; i++) { if(neutron_pairs[i].electron == electron) { bElectron_Paired = true; } if (neutron_pairs[i].proton == proton) { bProton_Paired = true; } } if (!bElectron_Paired && !bProton_Paired) { for (int i = 0; i < 12; i++) { if (!neutron_Pair_GO[i].activeSelf) { neutron_pairs[i].active = true; neutron_pairs[i].proton = proton; neutron_pairs[i].electron = electron; neutron_Pair_GO[i].SetActive(true); neutron_pairs[i].neutron = neutron_Pair_GO[i]; curr_active = i; break; } } } return; } neutron_Pair_GO[curr_active].transform.position = proton.transform.position; Vector3 vLA = proton.transform.position - electron.transform.position; Quaternion q = Quaternion.LookRotation(vLA); neutron_Pair_GO[curr_active].transform.rotation = q; } public void DeActivate_Pair_Outside_Of_Range() { Vector3 vDist; for (int i = 0; i < 12; i++) { if (neutron_pairs[i].active) { if (neutron_pairs[i].proton != null && neutron_pairs[i].electron != null) { vDist = neutron_pairs[i].proton.transform.position - neutron_pairs[i].electron.transform.position; if (vDist.magnitude > 1.8f * p2p_Diameter) { neutron_pairs[i].active = false; neutron_Pair_GO[i].active = false; neutron_pairs[i].proton = null; neutron_pairs[i].electron = null; } } } } }
private void Update()
{
Animate_Handle_Material();
}
}