public Bsdf(DifferentialGeometry dgShading, Normal nGeom, float eta = 1.0f) { _dgShading = dgShading; _ng = nGeom; _eta = eta; _nn = dgShading.Normal; _sn = Vector.Normalize(dgShading.DpDu); _tn = Normal.Cross(_nn, _sn); _bxdfs = new List <Bxdf>(); }
public Line Intersection(Surface s) { Vector direction = Normal.Cross(s.Normal); double det = direction.Magnitude * direction.Magnitude; if (det <= double.Epsilon) { //planes are parallel return(null); } // calculate a point on the line Point p = (Point)((direction.Cross(s.Normal).Scale(D)) + (Normal.Cross(direction).Scale(s.D))).Scale(1 / det); return(new Line(p, direction)); }
public Text(PrimitiveText text, object tag = null) : base(text.Color, tag) { _primitive = text; _primitives = new[] { _primitive }; _snapPoints = new[] { new EndPoint(Location) }; var rad = Rotation * MathHelper.DegreesToRadians; var right = new Vector(Math.Cos(rad), Math.Sin(rad), 0.0).Normalize() * Width; var up = Normal.Cross(right).Normalize() * Height; BoundingBox = BoundingBox.FromPoints( Location, Location + right, Location + up, Location + right + up); }
/// <summary> /// The volume of the bounding box. /// Note that antipodal points would result in an infinite number of great circles, but can /// be ignored since we are assuming the thickness of this solid is greater than 0. /// </summary> /// <param name="gaussianSphere">The gaussian sphere.</param> /// <param name="vector1">The vector1.</param> /// <param name="vector2">The vector2.</param> /// <param name="referenceArc">The reference arc.</param> internal GreatCircleOrthogonalToArc(GaussianSphere gaussianSphere, Vector3 vector1, Vector3 vector2, Arc referenceArc) { ArcList = new List <Arc>(); Intersections = new List <Intersection>(); var tempIntersections = new List <Intersection>(); ReferenceVertices = new List <Vertex>(); Normal = vector1.Cross(vector2); foreach (var arc in gaussianSphere.Arcs) { var segmentBool = false; //Create two planes given arc and the great circle var norm2 = arc.Nodes[0].Vector.Cross(arc.Nodes[1].Vector); //Check whether the planes are the same. if (Math.Abs(Normal[0] - norm2[0]) < 0.0001 && Math.Abs(Normal[1] - norm2[1]) < 0.0001 && Math.Abs(Normal[2] - norm2[2]) < 0.0001) { segmentBool = true; //All points intersect } if (Math.Abs(Normal[0] + norm2[0]) < 0.0001 && Math.Abs(Normal[1] + norm2[1]) < 0.0001 && Math.Abs(Normal[2] + norm2[2]) < 0.0001) { segmentBool = true; //All points intersect } //if (Normal[0].IsPracticallySame(norm2[0]) && Normal[1].IsPracticallySame(norm2[1]) && // Normal[2].IsPracticallySame(norm2[2])) segmentBool = true; //All points intersect //Check whether the planes are the same, but built with opposite normals. //if (Normal[0].IsPracticallySame(-norm2[0]) && Normal[1].IsPracticallySame(-norm2[1]) && // Normal[2].IsPracticallySame(-norm2[2])) segmentBool = true; //All points intersect if (segmentBool) { //The arc should be on the arc list. ArcList.Add(arc); } //Find points of intersection between two planes var position1 = Normal.Cross(norm2).Normalize(); var position2 = -1 * position1; var vertices = new[] { position1, position2 }; //Check to see if the intersection is on the arc. We already know it is on the great circle. for (var i = 0; i < 2; i++) { var l1 = arc.ArcLength; var l2 = ArcLength(arc.Nodes[0].Vector, vertices[i]); var l3 = ArcLength(arc.Nodes[1].Vector, vertices[i]); var total = l1 - l2 - l3; if (Math.Abs(total) > 0.00001) { continue; } var node = arc.NextNodeAlongRotation(referenceArc.Direction); //todo: NEED spherical distance along rotation. Below is an attempt //Subtract the reference arc direction vector from the node and determine where it intersects the great circle var theta = referenceArc.Direction[0] - node.Theta; var phi = referenceArc.Direction[1] - node.Phi; var x = Math.Cos(theta) * Math.Sin(phi); var y = Math.Sin(theta) * Math.Sin(phi); var z = Math.Cos(phi); var point = new Vector3(x, y, z); //Create two planes given the great circle and this new temporary arc var tempNorm = point.Cross(node.Vector); //Find points of intersection between two planes var position3 = Normal.Cross(tempNorm).Normalize(); var position4 = -1 * position3; var vertices2 = new[] { position3, position4 }; for (var j = 0; j < 2; j++) { var tempL1 = ArcLength(node.Vector, point); var tempL2 = ArcLength(node.Vector, vertices2[j]); var tempL3 = ArcLength(point, vertices2[j]); var tempTotal = tempL1 - tempL2 - tempL3; if (Math.Abs(tempTotal) > 0.00001) { continue; } var intersection = new Intersection(node, tempL3, arc); tempIntersections.Add(intersection); ArcList.Add(arc); break; } break; } } //Sort intersections var tempIntersections2 = tempIntersections.OrderBy(intersection => intersection.SphericalDistance).ToList(); //Remove duplicates for (var i = 0; i < tempIntersections2.Count - 1; i++) { var intersection1 = tempIntersections2[i]; var intersection2 = tempIntersections2[i + 1]; if (intersection1.Node != intersection2.Node) { Intersections.Add(intersection1); //Add the last intersection to the list if it was no the same as the current if (i == tempIntersections2.Count - 2) { Intersections.Add(intersection2); } } } //Add the reference vertices to a list foreach (var arc in ArcList) { foreach (var referenceVertex in arc.ReferenceVertices) { if (!ReferenceVertices.Contains(referenceVertex)) { ReferenceVertices.Add(referenceVertex); } } } }
/// <summary> /// The volume of the bounding box. /// Note that antipodal points would result in an infinite number of great circles, but can /// be ignored since we are assuming the thickness of this solid is greater than 0. /// </summary> /// <param name="gaussianSphere">The gaussian sphere.</param> /// <param name="vector1">The vector1.</param> /// <param name="vector2">The vector2.</param> /// <param name="referenceArc">The reference arc.</param> internal GreatCircleAlongArc(GaussianSphere gaussianSphere, Vector3 vector1, Vector3 vector2, Arc referenceArc) { var antiPoint1 = new Vector3(-referenceArc.Nodes[0].X, -referenceArc.Nodes[0].Y, -referenceArc.Nodes[0].Z); //var antiPoint2 = new[] { -referenceArc.Nodes[1].X, -referenceArc.Nodes[1].Y, -referenceArc.Nodes[1].Z }; ArcList = new List <Arc>(); Intersections = new List <Intersection>(); var tempIntersections = new List <Intersection>(); ReferenceVertices = new List <Vertex>(); Normal = vector1.Cross(vector2); foreach (var arc in gaussianSphere.Arcs) { if (arc == referenceArc) { continue; } var segmentBool = false; //Create two planes given arc and the great circle var norm2 = arc.Nodes[0].Vector.Cross(arc.Nodes[1].Vector).Normalize(); //Check whether the planes are the same. if (Math.Abs(Normal[0] - norm2[0]) < 0.0001 && Math.Abs(Normal[1] - norm2[1]) < 0.0001 && Math.Abs(Normal[2] - norm2[2]) < 0.0001) { segmentBool = true; //All points intersect } if (Math.Abs(Normal[0] + norm2[0]) < 0.0001 && Math.Abs(Normal[1] + norm2[1]) < 0.0001 && Math.Abs(Normal[2] + norm2[2]) < 0.0001) { segmentBool = true; //All points intersect } //if (Normal[0].IsPracticallySame(norm2[0]) && Normal[1].IsPracticallySame(norm2[1]) && // Normal[2].IsPracticallySame(norm2[2])) segmentBool = true; //All points intersect //Check whether the planes are the same, but built with opposite normals. //if (Normal[0].IsPracticallySame(-norm2[0]) && Normal[1].IsPracticallySame(-norm2[1]) && // Normal[2].IsPracticallySame(-norm2[2])) segmentBool = true; //All points intersect //Set the intersection vertices Vector3[] vertices; if (segmentBool) { vertices = new[] { arc.Nodes[0].Vector, arc.Nodes[1].Vector }; } else { //Find points of intersection between two planes var position1 = Normal.Cross(norm2).Normalize(); var position2 = -1 * position1; vertices = new[] { position1, position2 }; } for (var i = 0; i < 2; i++) { double l1; double l2; double l3; //If not on the same plane, check to see if intersection is on arc. if (!segmentBool) { l1 = arc.ArcLength; l2 = ArcLength(arc.Nodes[0].Vector, vertices[i]); l3 = ArcLength(arc.Nodes[1].Vector, vertices[i]); //Check to see if the intersection is on the arc. We already know it is on the great circle. //It is ok if the vertex == the node.Vector. var total = l1 - l2 - l3; if ((l2.IsNegligible() && l3.IsNegligible()) || Math.Abs(total) > 0.00001) { continue; //Go to next. } } var intersectionVertex = new Vertex(vertices[i]); //Find distance from the reference arc's antipodal point 1 in direction of the reference arc. l1 = referenceArc.ArcLength; l2 = Math.PI - referenceArc.ArcLength; l3 = ArcLength(referenceArc.Nodes[0].Vector, vertices[i]); var l4 = ArcLength(referenceArc.Nodes[1].Vector, vertices[i]); var l5 = ArcLength(antiPoint1, vertices[i]); Intersection intersection; //Case 1: Inbetween point1 and point2 var total1 = l1 - l3 - l4; //Case 2: Inbetween point2 and antiPoint1 var total2 = l2 - l4 - l5; if (Math.Abs(total1) < 0.00001 || Math.Abs(total2) < 0.00001) { intersection = new Intersection(intersectionVertex, l3, arc); tempIntersections.Add(intersection); continue; } //Case 3: Inbetween antiPoint1 and antiPoint2 //Case 4: Inbetween antiPoint2 and Point1 intersection = new Intersection(intersectionVertex, Constants.TwoPi - l3, arc); tempIntersections.Add(intersection); //Only one intersection is possible per arc, since the case of multiple intersections is captured above. break; } } var tempIntersections2 = tempIntersections.OrderBy(intersection => intersection.SphericalDistance).ToList(); //Remove duplicates for (var i = 0; i < tempIntersections2.Count - 1; i++) { var intersection1 = tempIntersections2[i]; var intersection2 = tempIntersections2[i + 1]; if (Math.Abs(intersection1.SphericalDistance - intersection2.SphericalDistance) > 0.00001) { Intersections.Add(intersection1); } //Add the last intersection to the list if it was no the same as the current if (i == tempIntersections2.Count - 2) { Intersections.Add(intersection2); } } }
public bool AreParallel(Surface s) { Vector cross = Normal.Cross(s.Normal); return(cross.Magnitude < double.Epsilon); }