Note that there are some explanatory texts on larger screens.

plurals
  1. PORay Tracing C# Triangle Intersection
    text
    copied!<p>So basicly I want to reflect a ray over a triangle. Here's my ray class</p> <pre><code>public sealed class Ray { public readonly Point3D Source; public readonly Point3D Direction; public readonly Color Light; public Ray(Point3D source, Point3D direction, Color light) { if (source == direction) { throw new ArgumentException("Source and Direction cannot be equal"); } this.Source = source; this.Direction = direction; this.Light = light; } } </code></pre> <p>Heres my Point3D class</p> <pre><code>public struct Point3D : IEquatable&lt;Point3D&gt; { public static readonly Point3D Zero = new Point3D(); public float X; public float Y; public float Z; public Point3D(float x, float y, float z) { this.X = x; this.Y = y; this.Z = z; } public override bool Equals(object obj) { if (!(obj is Point3D)) { return false; } return this.Equals((Point3D)obj); } public static bool operator ==(Point3D one, Point3D two) { return one.Equals(two); } public static bool operator !=(Point3D one, Point3D two) { return !one.Equals(two); } public static Point3D operator *(float n, Point3D v) { return new Point3D(v.X * n, v.Y * n, v.Z * n); } public static Point3D operator +(Point3D v1, Point3D v2) { return new Point3D(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z); } public static Point3D operator -(Point3D v1, Point3D v2) { return new Point3D(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z); } public static float operator *(Point3D v1, Point3D v2) { return (v1.X * v2.X) + (v1.Y * v2.Y) + (v1.Z * v2.Z); } public static float Magnitude(Point3D v) { return (float)Math.Sqrt(v * v); } public static Point3D Normalize(Point3D v) { float mag = Magnitude(v); float div = (mag == 0) ? float.PositiveInfinity : (1 / mag); return div * v; } public static Point3D Cross(Point3D v1, Point3D v2) { return new Point3D(((v1.Y * v2.Z) - (v1.Z * v2.Y)), ((v1.Z * v2.X) - (v1.X * v2.Z)), ((v1.X * v2.Y) - (v1.Y * v2.X))); } /// &lt;summary&gt; /// doesnt take square root /// &lt;/summary&gt; public static float FastDistance(Point3D v1, Point3D v2) { float x = v1.X - v2.X; x *= x; float y = v1.Y - v2.Y; y *= y; float z = v1.Z - v2.Z; z *= z; return x + y + z; } /// &lt;summary&gt; /// Takes square root: /// &lt;/summary&gt; public static float Distance(Point3D v1, Point3D v2) { return (float)Math.Sqrt(Point3D.FastDistance(v1, v2)); } public override int GetHashCode() { return this.X.GetHashCode() ^ this.Y.GetHashCode() ^ this.Y.GetHashCode(); } public override string ToString() { return this.X + ", " + this.Y + ", " + this.Z; } public bool Equals(Point3D other) { return this.X == other.X &amp;&amp; this.Y == other.Y &amp;&amp; this.Z == other.Z; } } </code></pre> <p>and finally here is where I need my method to be realized.</p> <pre><code>public interface ITriangleAccess { Triangle3D Find(Ray ray, out Point3D crossPoint); } public sealed class TriangleAccess : ITriangleAccess { private readonly List&lt;KeyValuePair&lt;float, Triangle3D&gt;&gt; trianglesByX; private readonly List&lt;Triangle3D&gt; allTriangles; public TriangleAccess(Body[] bodies) { if (null == bodies) { throw new ArgumentNullException("bodies"); } this.allTriangles = bodies.SelectMany((x) =&gt; x.Parts).ToList(); this.trianglesByX = bodies.SelectMany((x) =&gt; x.Parts).SelectMany((y) =&gt; new KeyValuePair&lt;float, Triangle3D&gt;[] { new KeyValuePair&lt;float,Triangle3D&gt;(y.Point1.X,y), new KeyValuePair&lt;float,Triangle3D&gt;(y.Point2.X,y), new KeyValuePair&lt;float,Triangle3D&gt;(y.Point3.X,y) }).ToList(); } public Triangle3D Find(Ray ray, out Point3D crossPoint) { crossPoint = Point3D.Zero; List&lt;Triangle3D&gt; relevant = this.GetRelevantTriangles(ray); Triangle3D absoluteTriangle = null; float min = float.MaxValue; foreach (Triangle3D item in relevant) { Point3D currentCrossPoint; if (this.RayIntersectTriangle(ray, item, out currentCrossPoint)) { float distance = Point3D.Distance(ray.Source, currentCrossPoint); if (distance &lt; min) { absoluteTriangle = item; crossPoint = currentCrossPoint; min = distance; } } } return absoluteTriangle; } public Ray Reflect(Ray ray, Point3D crossPoint, Triangle3D intersect) { //need this to be realized //please help } /// &lt;summary&gt; /// TODO: Finish this Up: /// &lt;/summary&gt; /// &lt;param name="ray"&gt;&lt;/param&gt; /// &lt;returns&gt;&lt;/returns&gt; private List&lt;Triangle3D&gt; GetRelevantTriangles(Ray ray) { return this.allTriangles; } private bool RayIntersectTriangle(Ray ray, Triangle3D triangle, out Point3D crossPoint) { // Find vectors for two edges sharing vert0 Point3D edge1 = triangle.Point2 - triangle.Point1; Point3D edge2 = triangle.Point3 - triangle.Point1; // Begin calculating determinant - also used to calculate barycentricU parameter Point3D pvec = Point3D.Cross(ray.Direction, edge2); // If determinant is near zero, ray lies in plane of triangle float det = edge1 * pvec; if (det &lt; 0.0001f) { crossPoint = Point3D.Zero; return false; } // Calculate distance from vert0 to ray origin Point3D tvec = ray.Source - triangle.Point1; // Calculate barycentricU parameter and test bounds float barycentricU = tvec * pvec; if (barycentricU &lt; 0.0f || barycentricU &gt; det) { crossPoint = Point3D.Zero; return false; } // Prepare to test barycentricV parameter Point3D qvec = Point3D.Cross(tvec, edge1); // Calculate barycentricV parameter and test bounds float barycentricV = ray.Direction * qvec; if (barycentricV &lt; 0.0f || barycentricU + barycentricV &gt; det) { crossPoint = Point3D.Zero; return false; } // Calculate pickDistance, scale parameters, ray intersects triangle float pickDistance = edge2 * qvec; float fInvDet = 1.0f / det; pickDistance *= fInvDet; barycentricU *= fInvDet; barycentricV *= fInvDet; crossPoint = MathHelper.BaryCentric(triangle, barycentricU, barycentricV); return true; } } </code></pre> <p>Thank you. P.S have patience with me... I'm just 15 :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload