// builds a map of the neighbors of each vector public void buildNeighborsDetails(Cell2 icell, Mesh mesh) { objectMesh = mesh; cell = icell; int[] t = mesh.triangles; //verticesHash = new ArrayList(mesh.vertices.Length); /*for (int i = 0; i < mesh.vertices.Length; i++) { * neighborsForVertex.Add(i, new List<int>()); * }*/ //vertexDetails2 tempDets; // Initialize vertexDetails2 array to each vertex. for (int i = 0; i < mesh.vertices.Length; i++) { vertexDetails2 tempDets = new vertexDetails2(); tempDets.vertexIndex = i; tempDets.vectorsToNeighbors = new List <Vector3>(); tempDets.neighborIndicesList = new List <int>(); tempDets.neighborIndicesByProbability = new List <int>(); //tempDets.probabilityPerNeighbor = new List<float>(); detailsForVertex.Add(i, tempDets); } // For each trio of indices of vectors that form a triangle, register that they are neighbors of each other... for (int i = 0; i < t.Length; i += 3) { // read the indices of the vertices that make up the tri int indexOfVert1 = t[i]; int indexOfVert2 = t[i + 1]; int indexOfVert3 = t[i + 2]; addAllVerticesToEachOthersLists(indexOfVert1, indexOfVert2, indexOfVert3); } calculateAngularProbability(); //calculateDensityForExocytosis(); }
// calculate the chances, per each vertex, to go to each of the neighbors, by the angles to each neighbor. void calculateAngularProbability() { float sumOfDensities = 0; float sumOfDistances; float sumOfInverseSquaredDistances; float prevDist; // Iterate over all vertices and calculate chances to go to each neighbor, by the angle to that neighnbor. for (int j = 0; j < detailsForVertex.Count; j++) { //if (j==900) { // Debug.Log("900"); //} vertexDetails2 tempDets = new vertexDetails2(); tempDets = detailsForVertex[j]; Vector3 vectorSum = Vector3.zero; // find the sum vector of all neighbors: for (int i = 0; i < detailsForVertex[j].neighborIndicesList.Count; i++) { vectorSum += detailsForVertex[j].vectorsToNeighbors[i].normalized; } if (vectorSum != Vector3.zero) { // creating a neighborDetail struct array for all neigbors, so it'd be easier to work with. List <neighborDetails> neighborDets = new List <neighborDetails>(); for (int i = 0; i < detailsForVertex[j].neighborIndicesList.Count; i++) { // find the projection of the neighbors on the plane defined by the sum vector as its normal. Vector3 mProjectedVector = Vector3.ProjectOnPlane(detailsForVertex[j].vectorsToNeighbors[i], vectorSum); neighborDets.Add(new neighborDetails() { projectedVector = mProjectedVector, neighborIndex = detailsForVertex[j].neighborIndicesList[i], fullAngle = Utils.phiInPlane(mProjectedVector, vectorSum) }); } // sorting the vectors indices by the size of the phi angle. Now we have the vectors in their order on the plane. List <neighborDetails> sortedNeighborDetails = neighborDets.OrderBy(neighbor => neighbor.fullAngle).ToList(); // calculate the angle span of each vector -- see function that does it. for (int i = 0; i < sortedNeighborDetails.Count; i++) { sortedNeighborDetails[i].angleFromPrevious = calcAngleFromPrevious(sortedNeighborDetails, i); sortedNeighborDetails[i].angleSpan = calcAngleSpan(sortedNeighborDetails, i); } float sumOfAngles = sortedNeighborDetails.Select(neighbor => neighbor.angleFromPrevious).Sum(); // I think it should be 360, but just in case. // Normalizing the array by the smallest member, so that there wouldn't be so many members in the 'by probability' array, and it would run faster. sortedNeighborDetails.ForEach(neighbor => { neighbor.relativeAngleSpan = (float)(neighbor.angleSpan / sumOfAngles); }); // remove extremely small angle spans - such angles mean that there's a duplicate path somewhere, which shouldn't appear sortedNeighborDetails = sortedNeighborDetails.Where(neighbor => neighbor.angleSpan > 1).ToList <neighborDetails>(); // finding the smallest member and calculating its division from 1 - then, when multiplying all members by this multiplier, the smallest would be 1 and all the rest would be bigger. This is a way to keep the proportional array small. //float multiplier = 1 / sortedNeighborDetails.Select(n => n.relativeAngleSpan).Min(); for (int i = 0; i < sortedNeighborDetails.Count; i++) { // now inserting the correlative number of neighbors to the probability - so that running a random on this list will effectively create a random with probability. int numOfNeighborsForProbability = Mathf.RoundToInt(sortedNeighborDetails[i].relativeAngleSpan * 100); /*if (numOfNeighborsForProbability > 10) { * Debug.Log("num of neighbors: " + numOfNeighborsForProbability); * } */ for (int k = 0; k < numOfNeighborsForProbability; k++) { tempDets.neighborIndicesByProbability.Add(sortedNeighborDetails[i].neighborIndex); } } } else // the only case where the sum of normalized vectors is the 0 vector is if they are orthogonal, the chances are equal between them. // Just copy the neighbor list { tempDets.neighborIndicesByProbability = tempDets.neighborIndicesList; } detailsForVertex[j] = tempDets; } }