public override void Draw(OpenGL gl) { // Drawing metagons is fairly easy, we save the vertex data, make a copy of // it, apply gravity, then draw the polygon. Afterwards, we restore it. VertexCollection oldVertices = vertices; VertexCollection newVertices = new VertexCollection(); foreach (Vertex v in vertices) { // Apply gravity, this means we need to know what other metagons there // are. // Find the closest vertex from the other metagon. double finddistance = -1; Vertex gravPoint = null; foreach (Vertex mV in other.Vertices) { Vertex temp = (mV /* + other.Translate*/) - (v + Translate); double tempdist = temp.Magnitude(); if (finddistance == -1 || tempdist < finddistance) { gravPoint = mV; finddistance = tempdist; } } Vertex toGrav = gravPoint - v; double distance = toGrav.Magnitude(); // The 'force' of gravity is the square root of this value, so it // only works well up cloes. double force = System.Math.Sqrt(distance); double growForce = System.Math.Sqrt(force); toGrav.UnitLength(); // Now we push this vector along by the required amount. Vertex newV = v + (toGrav * (float)force); newVertices.Add(newV); } vertices = newVertices; // Draw it. base.Draw(gl); }
/// <summary> /// This function tests to see if a ray interesects the polygon. /// </summary> /// <param name="ray">The ray you want to test.</param> /// <param name="pointOfIntersection">The actual point of intersection (if any).</param> /// <returns>The distance from the origin of the ray to the intersection, or -1 if there /// is no intersection.</returns> public Intersection TestIntersection(Ray ray) { Intersection intersect = new Intersection(); // This code came from jgt intersect_triangle code (search dogpile for it). foreach (Face face in faces) { // Assert that it's a triangle. if (face.Count != 3) { continue; } // Find the point of intersection upon the plane, as a point 't' along // the ray. Vertex point1OnPlane = vertices[face.Indices[0].Vertex]; Vertex point2OnPlane = vertices[face.Indices[1].Vertex]; Vertex point3OnPlane = vertices[face.Indices[2].Vertex]; Vertex midpointOpp1 = (point2OnPlane + point3OnPlane) / 2; Vertex midpointOpp2 = (point1OnPlane + point3OnPlane) / 2; Vertex midpointOpp3 = (point1OnPlane + point2OnPlane) / 2; Vertex planeNormal = face.GetSurfaceNormal(this); Vertex diff = point1OnPlane - ray.origin; float s1 = diff.ScalarProduct(planeNormal); float s2 = ray.direction.ScalarProduct(planeNormal); if (s2 == 0) { continue; } float t = s1 / s2; if (t < 0) { continue; } float denomintor = planeNormal.ScalarProduct(ray.direction); if (denomintor < 0.00001f && denomintor > -0.00001f) { continue; // doesn't intersect the plane. } // Vertex v = point1OnPlane - ray.origin; // float t = (v.ScalarProduct(planeNormal)) / denomintor; // Now we can get the point of intersection. Vertex vIntersect = ray.origin + (ray.direction * t); // Do my cool test. Vertex vectorTo1 = vIntersect - point1OnPlane; Vertex vectorTo2 = vIntersect - point2OnPlane; Vertex vectorTo3 = vIntersect - point3OnPlane; Vertex vectorMidTo1 = midpointOpp1 - point1OnPlane; Vertex vectorMidTo2 = midpointOpp2 - point2OnPlane; Vertex vectorMidTo3 = midpointOpp3 - point3OnPlane; if (vectorTo1.Magnitude() > vectorMidTo1.Magnitude()) { continue; } if (vectorTo2.Magnitude() > vectorMidTo2.Magnitude()) { continue; } if (vectorTo3.Magnitude() > vectorMidTo3.Magnitude()) { continue; } if (intersect.closeness == -1 || t < intersect.closeness) { // It's f*****g intersection city man intersect.point = vIntersect; intersect.intersected = true; intersect.normal = planeNormal; intersect.closeness = t; } #region The Old Raytracing code //// Get the three vertices in the face. //Vertex v1 = vertices[face.Indices[0].Vertex]; //Vertex v2 = vertices[face.Indices[1].Vertex]; //Vertex v3 = vertices[face.Indices[2].Vertex]; //// Find the vectors for the two edges of the tri that share v1. //Vertex edge1 = v2 - v1; //Vertex edge2 = v3 - v1; //// Begin calculating the determinant, also used to calculate U parameter. //Vertex pVector = ray.direction.VectorProduct(edge2); //float determinant = edge1.ScalarProduct(pVector); //// If the determinant is less than zero, it's behind the triangle i.e. //// the back face. If it's very close to zero (errorvalue) it on the plane. //float errorvalue = 0.000001f; //if(determinant < errorvalue && determinant > -errorvalue) // continue; //// Calculate the distance from vertex 1 to ray origin. //Vertex tVector = ray.origin - v1; //// Calculate the U parameter and test bounds. //float u = tVector.ScalarProduct(pVector); //if(u < 0 || u > determinant) // continue; //// Prepare to test V parameter. //Vertex qVector = tVector.VectorProduct(edge1); //// Calculate the v parameter and test bounds. //float v = ray.direction.ScalarProduct(qVector); //if(v < 0 || v > determinant) // continue; //// Calculate t, scale parameters. //float t = edge2.ScalarProduct(qVector); //float inverseDeterminant = 1.0f / determinant; //t *= inverseDeterminant; //u *= inverseDeterminant; //v *= inverseDeterminant; //// Now we have a point of intersection. Yeah. Let's got some //// magnitude into the action. //Vertex pointOfIntersection = new Vertex(t, u, v); //// OK! We've got an intersection, find how far away it it by simple //// stuff: make a vector from the origin and the intersection, and //// get it's magnitude. //Vertex vOriginToIntersection = pointOfIntersection - ray.origin; //float magnitude = (float)vOriginToIntersection.Magnitude(); //// Is this magnitude is smaller (closer) than any we've found so far? //if(intersect.closeness == -1 || magnitude < intersect.closeness) //{ // // This is the closest intersection yet, so fill in the // // intersect structure. // intersect.point.Set(t, u, v); // intersect.intersected = true; // intersect.normal = face.GetSurfaceNormal(this); // intersect.closeness = magnitude; //} #endregion } return(intersect); }
public override string ToString() { return string.Format("back:{0}|{3:0.00},up:{1}|{4:0.00},right:{2}|{5:0.00}", FormatVertex(back), FormatVertex(up), FormatVertex(right), back.Magnitude(), up.Magnitude(), right.Magnitude()); //return base.ToString(); }