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;

                    }
                }
            }
        }
    }

Steric Repulsion

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>
So as an example

use 4 protons 2 inner 2 outer electrons (helium) tetrahedron, 2 paired electrons !
use 7 protons 4 electrons (lithium) probably most difficult one
use 12 protons 12 electrons (6 inner 6 outer) should yield 6 pairs of neutrons / deuterium nuclets and 6 orbiting auto settling outer electrons
 
combine nuclets, implement nuclets one at a time (2, 4, 6, 7, 11, 12 etc)
combine 12 p with 2 p for example (carbon with Deuterium)
2 and 2 (2 times Deuterium)
etc
 
Edo
 
On Thu, Jan 25, 2018 at 9:08 AM, Edo Kael <edwinkaal00@gmail.com> wrote:

http://becomingborealis.com/clustering-tetrahedrons-video/

 
This behavior here is more or less how matter 'condenses' / how atoms are created. However we need to keep in mind the 3 main structures / the morphing of geometry.
4 tetrahedron become a lithium (pentagonal bypiramid) and a couple of those integrated in each other become morphed the icosahedron (Carbon).
So in order to mimic plasma condensation properly. we need to implement a couple of steps;
- implement a duality (proton + electron)
- Use the double sphere idea (electron outer sphere is ghostly) and overlap neutralizes/"cancels out each other" automatically 5/12 overlap?)
- Use 2 kinds of electrons, uncharged (neutrons), charge ups (outer electrons, cannot approach the nucleus!)
- Let the model create the shapes that are possible by adding specific numbers (creation of the elements)
- Put several and combinations of these elements together (fusion - chemistry - fission)
 
Got 5 steps identified now 🙂
I am guestimating this would actually show the nature of an atom.......
 
Edo
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>
just to add another suggestion,,,,

 
Create 2 types of electrons. the ones you have now with the attribute that they will be first come first serve to make a overlapping connection and
another electron that is 'charged' up representing the outer electrons. they should stay at a distance at least greater then the diameter of the nucleus can be to keep them at bay but still be able to see their related position.
 
Edo
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>
David,

 
It was delightful sight to see the behavior of the proton electron in your 3D environment!
 
If I may make a next suggestion, then it would be to do the following.
 
When an electron starts to overlap with a proton, it should not yield anymore to another electron. The other can then only connect to left over places. like a first come first serve. This way in a system of 2 p and 2 e it would and i start with 2 p and 1 e it would stabilize and then when we release the second e it should not be able to distort the already made connection but can only choose the left over 2 half positive spots.
 
Edo

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 protons
 
most 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);
    }

    private void Update()
    {
        Animate_Handle_Material();
    }
}

Becoming Borealis 2018