/// <summary> /// Predict from each possible triange, returning each candidate /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="n"></param> /// <returns>Only returns plausible candidates, if all are bad, the result is empty</returns> internal List <System.Drawing.Point> GetCandidates(int x, int y, List <PointMapping> n) { if (n.Count < 3) { throw new ArgumentException("at least 3 neighbours needed"); } var targ = new System.Drawing.Point(x, y); var poss = new List <System.Drawing.Point>(); for (int i = 0; i < n.Count - 2; i++) { for (int j = i + 1; j < n.Count; j++) { for (int k = j + 1; k < n.Count; k++) { var b = new BarycentricCoordinate(targ, n[i].Image, n[j].Image, n[k].Image); if (b.IsNearby) { poss.Add(b.GetCartesianCoordinates(n[i].Screen, n[j].Screen, n[k].Screen)); } } } } return(poss); }
public override bool FindIntersection(Ray ray, out Intersection intersect) { intersect = new Intersection(); if (this.accelerationManager != null && this.accelerationManager.FindIntersection(ray, out intersect)) { if (this.shadeType == ShadeType.Phong) { MeshTriangle t = (MeshTriangle)intersect.HitPrimitive; BarycentricCoordinate bary = t.CurrentBarycentricCoordinate; Vector3D v1 = bary.Alpha * t.Vertex1.Normal; Vector3D v2 = bary.Beta * t.Vertex2.Normal; Vector3D v3 = bary.Gama * t.Vertex3.Normal; intersect.Normal = (v1 + v2 + v3); intersect.Normal.Normalize(); } if (intersect.Normal * ray.Direction > 0) { intersect.Normal.Flip(); } intersect.HitPrimitive = this; intersect.HitPrimitive.Material = this.material; return(true); } return(false); }
//[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.Synchronized)] public override bool FindIntersection(Ray ray, out Intersection intersect) { intersect = new Intersection(); //if (!this.BoundBox.Intersect(ray)) { // return false; //} if (this.manager != null && this.manager.FindIntersection(ray, out intersect)) { if (this.shadeType == ShadeType.Phong) { Triangle t = (Triangle)intersect.HitPrimitive; BarycentricCoordinate bary = t.CurrentBarycentricCoordinate; Vector3D v1 = bary.Alpha * t.NormalOnVertex1; Vector3D v2 = bary.Beta * t.NormalOnVertex2; Vector3D v3 = bary.Gama * t.NormalOnVertex3; intersect.Normal = (v1 + v2 + v3); intersect.Normal.Normalize(); } if (intersect.Normal * ray.Direction > 0) { intersect.Normal.Flip(); } intersect.HitPrimitive = this; intersect.HitPrimitive.Material = this.material; return(true); } return(false); }
public MeshTriangle(MeshVertex vertex1, MeshVertex vertex2, MeshVertex vertex3) { this.Vertex1 = vertex1; this.Vertex2 = vertex2; this.Vertex3 = vertex3; this.visible = true; this.CurrentBarycentricCoordinate = BarycentricCoordinate.Zero; this.material = null; }
public override Vector3D NormalOnPoint(Point3D pointInPrimitive) { foreach (Triangle tri in this.triangles) { if (tri.PointInTriangle(pointInPrimitive)) { BarycentricCoordinate bary = tri.CurrentBarycentricCoordinate; Vector3D v1 = bary.Alpha * tri.NormalOnVertex1; Vector3D v2 = bary.Beta * tri.NormalOnVertex2; Vector3D v3 = bary.Gama * tri.NormalOnVertex3; return(v1 + v2 + v3); } } return(Vector3D.Zero); }
public override Point FromPresentation(Point p) { var x = (int)Math.Round(p.X); var y = (int)Math.Round(p.Y); var b1 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopLeft, Grid.TopRight, Grid.BottomLeft); var p1 = b1.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Top), new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Top), new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Bottom)); //return p1; //if (b1.IsInside) // return p1; var b2 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopLeft, Grid.BottomLeft, Grid.BottomRight); var p2 = b2.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Top), new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Bottom), new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Bottom)); var b3 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopRight, Grid.BottomLeft, Grid.BottomRight); var p3 = b3.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Top), new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Bottom), new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Bottom)); var b4 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopLeft, Grid.TopRight, Grid.BottomRight); var p4 = b4.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Top), new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Top), new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Bottom)); //return p2; //if (b2.IsInside) //{ // return p2; //} if (!(b1.IsInside || b3.IsInside || b2.IsInside || b4.IsInside)) { return(new Point(-1.0f, -1.0f)); } return(new Point((p1.X + p2.X + p3.X + p4.X) / 4.0f, (p1.Y + p2.Y + p3.Y + p4.Y) / 4.0f)); //if (!b1.IsInside && !b2.IsInside) // return new Point(); //return new Point((int) Math.Round((p1.X + p2.X)/2.0), (int) Math.Round((p1.Y + p2.Y)/2.0)); }
/// <summary> /// Converts to Trilinear coordinates. /// </summary> /// <param name="vertexA">The vertex a.</param> /// <param name="vertexB">The vertex b.</param> /// <param name="vertexC">The vertex c.</param> /// <returns>TrilinearCoordinate.</returns> public TrilinearCoordinate ToTrilinear(CartesianCoordinate vertexA, CartesianCoordinate vertexB, CartesianCoordinate vertexC) { BarycentricCoordinate barycentric = ToBarycentric(vertexA, vertexB, vertexC); return(barycentric.ToTrilinear(vertexA, vertexB, vertexC)); }
//public override bool FindIntersection(Ray ray, out Intersection intersect) { // intersect = new Intersection(); // /* orientation of the ray with respect to the triangle's normal, // also used to calculate output parameters*/ // float det = -(ray.Direction * this.normalNonNormalized); // /* the non-culling branch */ // /* if determinant is near zero, ray is parallel to the plane of triangle */ // if ( det.NearZero()) { // return false; // } // /* calculate vector from ray origin to this.vertex1 */ // Vector3D vect0 = this.vertex1 - ray.Origin; // /* normal vector used to calculate u and v parameters */ // Vector3D nvect = ray.Direction ^ vect0; // float inv_det = 1.0f / det; // /* calculate vector from ray origin to this.vertex2*/ // Vector3D vect1 = this.vertex2 - ray.Origin; // /* calculate v parameter and test bounds */ // float v = -(vect1 * nvect) * inv_det; // if (v < 0.0f || v > 1.0f) { // return false; // } // /* calculate vector from ray origin to this.vertex3*/ // vect1 = this.vertex3 - ray.Origin; // /* calculate v parameter and test bounds */ // float u = (vect1 * nvect) * inv_det; // if (u < 0.0f || u + v > 1.0f) { // return false; // } // const double epsilon = 2E-2; // float alpha = 1.0f - (u + v); // if (this.Wireframed && (!u.NearZero(epsilon) && !v.NearZero(epsilon) && !alpha.NearZero(epsilon))) // { // return false; // } // /* calculate t, ray intersects triangle */ // float t = -(vect0 * this.normalNonNormalized) * inv_det; // //if (t < 100) // // return false; // // return 1; // if (t >= MathUtil.Epsilon) // { // intersect.Normal = this.normal; // intersect.TMin = t; // intersect.HitPoint = ray.Origin + (t * ray.Direction); // this.CurrentBarycentricCoordinate = new BarycentricCoordinate(alpha, u, v); // intersect.HitPrimitive = this; // if (this.material != null && this.material.IsTexturized) { // //int widthTex = this.material.Texture.Width - 1; // //int heightTex = this.material.Texture.Height - 1; // //this.material.Color = this.material.Texture.GetPixel((int)(u * widthTex), (int)(v * heightTex)); // intersect.CurrentTextureCoordinate.U = u; // intersect.CurrentTextureCoordinate.V = v; // } // return true; // } // return false; //} #endregion public override bool FindIntersection(Ray ray, out Intersection intersect) { intersect = new Intersection(); float u, v; /* begin calculating determinant - also used to calculate U parameter */ Vector3D pvec = ray.Direction ^ this.edge2; /* if determinant is near zero, ray lies in plane of triangle */ float det = this.edge1 * pvec; /* calculate distance from vert0 to ray origin */ Vector3D tvec = ray.Origin - this.vertex1; float inv_det = 1.0f / det; Vector3D qvec = tvec ^ this.edge1; if (det > MathUtil.Epsilon) { u = (tvec * pvec); if (u < 0.0 || u > det) { return(false); } /* calculate V parameter and test bounds */ v = (ray.Direction * qvec); if (v < 0.0 || u + v > det) { return(false); } } else if (det < -MathUtil.Epsilon) { /* calculate U parameter and test bounds */ u = (tvec * pvec); if (u > 0.0 || u < det) { return(false); } /* calculate V parameter and test bounds */ v = (ray.Direction * qvec); if (v > 0.0 || u + v < det) { return(false); } } else { return(false); /* ray is parallell to the plane of the triangle */ } u *= inv_det; v *= inv_det; float alpha = 1.0f - (u + v); const double epsilon = 2.5E-2; if (this.Wireframed && (!u.NearZero(epsilon) && !v.NearZero(epsilon) && !alpha.NearZero(epsilon))) { return(false); } intersect.Normal = this.normal; intersect.TMin = (edge2 * qvec) * inv_det; if (intersect.TMin >= MathUtil.Epsilon) { intersect.HitPoint = ray.Origin + (intersect.TMin * ray.Direction); this.CurrentBarycentricCoordinate = new BarycentricCoordinate(alpha, u, v); intersect.HitPrimitive = this; if (this.material != null && this.material.IsTexturized) { int widthTex = this.material.Texture.Width - 1; int heightTex = this.material.Texture.Height - 1; this.material.DiffuseColor = this.material.Texture.GetPixel((int)(u * widthTex), (int)(v * heightTex)); intersect.CurrentTextureCoordinate.U = u; intersect.CurrentTextureCoordinate.V = v; } return(true); } return(false); }
//From http://jgt.akpeters.com/papers/GuigueDevillers03/ray_triangle_intersection.html public bool FindIntersection(Ray ray, out Intersection intersect) { intersect = new Intersection(); Vector3D vect0, vect1, nvect; float det, inv_det; vect0 = this.Vertex2.Position - this.Vertex1.Position; vect1 = this.Vertex3.Position - this.Vertex1.Position; Vector3D normalNonNormalized = vect0 ^ vect1; /* orientation of the ray with respect to the triangle's normal, * also used to calculate output parameters*/ det = -(ray.Direction * normalNonNormalized); #if TEST_CULL /* define TEST_CULL if culling is desired */ if (det < MathUtil.Epsilon) { return(false); } /* calculate vector from ray origin to this.vertex1 */ vect0 = this.Vertex1.Position - ray.Origin; /* vector used to calculate u and v parameters */ nvect = ray.Direction ^ vect0; /* calculate vector from ray origin to this.vertex2*/ vect1 = this.Vertex2.Position - ray.Origin; /* calculate unnormalized v parameter and test bounds */ float v = -(vect1 * nvect); if (v < 0.0 || v > det) { return(false); } /* calculate vector from ray origin to this.vertex3*/ vect1 = this.Vertex3.Position - ray.Origin; /* calculate unnormalized v parameter and test bounds */ float u = vect1 * nvect; if (u < 0.0 || u + v > det) { return(false); } /* calculate unormalized t parameter */ float t = -(vect0 * normalNonNormalized); inv_det = 1.0f / det; /* calculate u v t, ray intersects triangle */ u = u * inv_det; v = v * inv_det; t = t * inv_det; #else /* the non-culling branch */ /* if determinant is near zero, ray is parallel to the plane of triangle */ if (det.NearZero()) { return(false); } /* calculate vector from ray origin to this.vertex1 */ vect0 = this.Vertex1.Position - ray.Origin; /* normal vector used to calculate u and v parameters */ nvect = ray.Direction ^ vect0; inv_det = 1.0f / det; /* calculate vector from ray origin to this.vertex2*/ vect1 = this.Vertex2.Position - ray.Origin; /* calculate v parameter and test bounds */ float v = -(vect1 * nvect) * inv_det; if (v < 0.0f || v > 1.0f) { return(false); } /* calculate vector from ray origin to this.vertex3*/ vect1 = this.Vertex3.Position - ray.Origin; /* calculate v parameter and test bounds */ float u = (vect1 * nvect) * inv_det; if (u < 0.0f || u + v > 1.0f) { return(false); } /* calculate t, ray intersects triangle */ float t = -(vect0 * normalNonNormalized) * inv_det; #endif //if (t < 100) // return false; // return 1; //if (t < 100) //FIXME: the correct is t < 0, but dont work, why? tell me you! =P //{ // return false; //} if (t >= 0) { intersect.TMin = t; intersect.Normal = Vector3D.Normal(this.Vertex1.Position, this.Vertex2.Position, this.Vertex3.Position); intersect.HitPoint = ray.Origin + (t * ray.Direction); this.CurrentBarycentricCoordinate = new BarycentricCoordinate(1.0f - (u + v), u, v); intersect.HitPrimitive = this; return(true); } return(false); }