public bool TryGetSceneNear(Vector3d position, bool onlyEnabled, out SceneInfo sceneInfo) { IScene[] scenes = null; if (m_sceneFactory != null) { scenes = m_sceneFactory.GetScenes(); } IScene closestScene = null; double minDist = Double.MaxValue; if (scenes != null) { for (int i = 0; i < scenes.Length; i++) { IScene scene = scenes[i]; // Get the midpoint of this scene Vector3d midpoint = (scene.MaxPosition + scene.MinPosition) * 0.5d; // Compare this distance against the current minimum distance (squared, to avoid an unncessary sqrt) double distance = Vector3d.DistanceSquared(position, midpoint); if (distance < minDist) { minDist = distance; closestScene = scene; } } } if (closestScene != null) { sceneInfo = SceneInfo.FromScene(closestScene); return(true); } sceneInfo = null; return(false); }
bool is_same_triangle(ref Vector3d a, ref Vector3d b, ref Vector3d c, ref Vector3d x, ref Vector3d y, ref Vector3d z, double tolSqr) { if (a.DistanceSquared(x) < tolSqr) { if (b.DistanceSquared(y) < tolSqr && c.DistanceSquared(z) < tolSqr) { return(true); } if (b.DistanceSquared(z) < tolSqr && c.DistanceSquared(y) < tolSqr) { return(true); } } else if (a.DistanceSquared(y) < tolSqr) { if (b.DistanceSquared(x) < tolSqr && c.DistanceSquared(z) < tolSqr) { return(true); } if (b.DistanceSquared(z) < tolSqr && c.DistanceSquared(x) < tolSqr) { return(true); } } else if (a.DistanceSquared(z) < tolSqr) { if (b.DistanceSquared(x) < tolSqr && c.DistanceSquared(y) < tolSqr) { return(true); } if (b.DistanceSquared(y) < tolSqr && c.DistanceSquared(x) < tolSqr) { return(true); } } return(false); }
bool is_same_edge(ref Vector3d a, ref Vector3d b, ref Vector3d c, ref Vector3d d) { return((a.DistanceSquared(c) < merge_r2 && b.DistanceSquared(d) < merge_r2) || (a.DistanceSquared(d) < merge_r2 && b.DistanceSquared(c) < merge_r2)); }
public bool FindInBall(Vector3d pt, double r, int[] buffer, out int buffer_count) { buffer_count = 0; double halfCell = CellSize * 0.5; Vector3i idx = indexF.ToGrid(pt); Vector3d center = indexF.FromGrid(idx) + halfCell * Vector3d.One; if (r > CellSize) { throw new ArgumentException("PointSetHashtable.FindInBall: large radius unsupported"); } double r2 = r * r; // check all in this cell PointList center_cell = Grid.Get(idx, false); if (center_cell != null) { foreach (int vid in center_cell) { if (pt.DistanceSquared(Points.GetVertex(vid)) < r2) { if (buffer_count == buffer.Length) { return(false); } buffer[buffer_count++] = vid; } } } // if we are close enough to cell border we need to check nbrs // [TODO] could iterate over fewer cells here, if r is bounded by CellSize, // then we should only ever need to look at 3, depending on which octant we are in. if ((pt - center).MaxAbs + r > halfCell) { for (int ci = 0; ci < 26; ++ci) { Vector3i ioffset = gIndices.GridOffsets26[ci]; // if we are within r from face, we need to look into it var ptToFaceCenter = new Vector3d( center.x + halfCell * ioffset.x - pt.x, center.y + halfCell * ioffset.y - pt.y, center.z + halfCell * ioffset.z - pt.z); if (ptToFaceCenter.MinAbs > r) { continue; } PointList ncell = Grid.Get(idx + ioffset, false); if (ncell != null) { foreach (int vid in ncell) { if (pt.DistanceSquared(Points.GetVertex(vid)) < r2) { if (buffer_count == buffer.Length) { return(false); } buffer[buffer_count++] = vid; } } } } } return(true); }
public override void Selected(SelectionType button) { nullifyHitPos = true; transform.parent.SendMessage("Selected", button, SendMessageOptions.DontRequireReceiver); if (button == SelectionType.SELECTALL) { BlockMove = true; } else { MeshFilter mf = GetComponent <MeshFilter>(); Mesh mesh = mf.sharedMesh; currentHit = transform.InverseTransformPoint(AppState.instance.lastHitPosition); Vector3d target = currentHit; System.Random rand = new System.Random(); int count = 0; // // The algorithm will find local optima - repeat until you get the tru optima // but limit the interation using a count // Int32 current = 0; while (count < dmesh.VertexCount) { count++; // // choose a random starting point // current = rand.Next(0, dmesh.VertexCount); Vector3d vtx = dmesh.GetVertex(current); double currentDist = vtx.DistanceSquared(target); // // find the ring of triangles around the current point // int iter = 0; while (true) { iter++; // throw new InvalidOperationException("Meh One Ring operation invalid : " + res.ToString()); // // Interate through the vertices in the one Ring and find the clost to the target point // bool flag = false; foreach (Int32 v in dmesh.VtxVerticesItr(current)) { Vector3d thisVtx = dmesh.GetVertex(v); double thisDist = thisVtx.DistanceSquared(target); if (thisDist < currentDist) { flag = true; current = v; vtx = thisVtx; currentDist = thisDist; } } // // if the current point as closest - then have a local optima // if (!flag) { break; } } // // we now have a local optima // to check for a global optima look to see if hit is contained by one of the triangles in the one ring // bool f2 = false; foreach (Int32 t in dmesh.VtxTrianglesItr(current)) { Index3i tri = dmesh.GetTriangle(t); Triangle3d triangle = new Triangle3d( dmesh.GetVertex(tri.a), dmesh.GetVertex(tri.b), dmesh.GetVertex(tri.c) ); double[] xs = new double[3] { triangle.V0.x, triangle.V1.x, triangle.V2.x }; double[] ys = new double[3] { triangle.V0.y, triangle.V1.y, triangle.V2.y }; double[] zs = new double[3] { triangle.V0.z, triangle.V1.z, triangle.V2.z }; if ( target.x >= xs.Min() && target.x <= xs.Max() && target.y >= ys.Min() && target.y <= ys.Max() && target.z >= zs.Min() && target.z <= zs.Max() ) { f2 = true; currentHitTri = tri; } } // // if we found on triamgle that contain the current hit then we have finished // if (f2) { break; } } if (count >= dmesh.VertexCount) { // // This is the unoptimized verion but it is guaranteed to find a solution if one exits // current = -1; float currentDist = float.MaxValue; if (currentHit != null) { for (int i = 0; i < mesh.vertices.Length; i++) { Vector3 vtx = mesh.vertices[i]; float dist = (currentHit - vtx).sqrMagnitude; if (dist < currentDist) { current = i; currentDist = dist; } } } // // Check that the closet vertex to the point is an actual solution // bool f2 = false; foreach (Int32 t in dmesh.VtxTrianglesItr(current)) { Index3i tri = dmesh.GetTriangle(t); Triangle3d triangle = new Triangle3d( dmesh.GetVertex(tri.a), dmesh.GetVertex(tri.b), dmesh.GetVertex(tri.c) ); double[] xs = new double[3] { triangle.V0.x, triangle.V1.x, triangle.V2.x }; double[] ys = new double[3] { triangle.V0.y, triangle.V1.y, triangle.V2.y }; double[] zs = new double[3] { triangle.V0.z, triangle.V1.z, triangle.V2.z }; if ( target.x >= xs.Min() && target.x <= xs.Max() && target.y >= ys.Min() && target.y <= ys.Max() && target.z >= zs.Min() && target.z <= zs.Max() ) { f2 = true; currentHitTri = tri; } } // // if we found on triamgle that contain the current hit then we have finished // if (!f2) { Debug.LogError(" Mesh Vertex Search : No Solution Found"); return; } } selectedVertex = current; sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.position = transform.TransformPoint(mesh.vertices[current]); sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); sphere.transform.parent = transform; } }