/// <summary> /// /// </summary> /// <param name="vertices"></param> /// <param name="axis"></param> /// <returns></returns> public Projection Project(Vector2[] vertices, Vector2 axis) { double min = axis.Dot(vertices[0]); double max = min; for (int i = 1; i < vertices.Length; i++) { // NOTE: the axis must be normalized to get accurate projections double p = axis.Dot(vertices[i]); if (p < min) { min = p; } else if (p > max) { max = p; } } return new Projection(min, max); }
public static MinkowskiDiff Support(Entity Object1, Entity Object2, Vector2 axis) { Matrix3x3 transform1, transform2; { Matrix3x3 rotation1 = Matrix3x3.RotationZ(-Object1.Orientation); Matrix3x3 translation1 = new Matrix3x3(1, 0, Object1.Position.X, 0, 1, Object1.Position.Y, 0, 0, 1); transform1 = Matrix3x3.Multiply(translation1, rotation1); Matrix3x3 rotation2 = Matrix3x3.RotationZ(-Object2.Orientation); Matrix3x3 translation2 = new Matrix3x3(1, 0, Object2.Position.X, 0, 1, Object2.Position.Y, 0, 0, 1); transform2 = Matrix3x3.Multiply(translation2, rotation2); } float max1 = axis.Dot(Object1.Shape.Vertices[0].Transform(transform1)); Vector2 maxp1 = Object1.Shape.Vertices[0].Transform(transform1); float max2 = axis.Dot(Object2.Shape.Vertices[0].Transform(transform2)); Vector2 maxp2 = Object2.Shape.Vertices[0].Transform(transform2); for (int i = 1; i < Object1.Shape.Vertices.Length; i++) { float dot = axis.Dot(Object1.Shape.Vertices[i].Transform(transform1)); if (max1 < dot) { max1 = dot; maxp1 = Object1.Shape.Vertices[i].Transform(transform1); } } for (int i = 1; i < Object2.Shape.Vertices.Length; i++) { float dot = axis.Dot(Object2.Shape.Vertices[i].Transform(transform2)); if (max2 > dot) { max2 = dot; maxp2 = Object2.Shape.Vertices[i].Transform(transform2); } } return new MinkowskiDiff(maxp1, maxp2); }
public void CalculateJ() { PhysicsEntity p1 = (PhysicsEntity)Object1; PhysicsEntity p2 = (PhysicsEntity)Object2; Vector2 p = (Point1 + Point2) / 2; float e = 0.1f; //Restitution rAP = (p - p1.Position).Perpendicular(); rBP = (p - p2.Position).Perpendicular(); Vector2 vAP = p1.Velocity + p1.Omega * rAP; Vector2 vBP = p2.Velocity + p2.Omega * rBP; Vector2 vAB = vAP - vBP; float j = -(1 + e) * vAB.Dot(N); float j1 = N.Dot(N) * (p1.MassInv + p2.MassInv); float j2 = (float)Math.Pow(rAP.Dot(N), 2) * p1.InertiaInv; float j3 = (float)Math.Pow(rBP.Dot(N), 2) * p2.InertiaInv; //j /= Data.N.Dot(Data.N) * (MassInv + p2.MassInv) + (float)Math.Pow(rAP.Dot(Data.N), 2) * InertiaInv + (float)(Math.Pow(rBP.Dot(Data.N), 2) * p2.InertiaInv); J = j / (j1 + j2 + j3); }
private static IResult IntersectionDetailsParallel(Vector2 d0, Vector2 d1, Vector2 e, Point2 a, Point2 b, Point2 c, Point2 d) { Contract.Ensures(Contract.Result<IResult>() != null); var squareMagnitude0 = d0.GetMagnitudeSquared(); var d0DotD1 = d0.Dot(d1); var s1 = d0.Dot(e) / squareMagnitude0; var s2 = s1 + (d0DotD1 / squareMagnitude0); double sMin, sMax; if (s1 <= s2) { sMin = s1; sMax = s2; } else { sMin = s2; sMax = s1; } if (sMax < 0.0 || sMin > 1.0) return DefaultNoIntersection; // no intersection if (sMax == 0.0) return new PointResult(a, 0.0, a == c ? 0.0 : 1.0); // the start point if (sMin == 1.0) return new PointResult(b, 1.0, b == c ? 0.0 : 1.0); // the end point PointResult resultA; PointResult resultB; double squareMagnitude1; if (sMin <= 0.0 && sMax >= 1.0) { squareMagnitude1 = d1.GetMagnitudeSquared(); var t1 = d1.Dot(e.GetNegative()) / squareMagnitude1; resultA = new PointResult(a, 0.0, t1); resultB = new PointResult(b, 1.0, t1 + (d0DotD1 / squareMagnitude1)); } else if (sMin >= 0.0 && sMax <= 1.0) { // reuse s1 and s2 from above resultA = new PointResult(c, s1, 0.0); resultB = new PointResult(d, s2, 1.0); } else { squareMagnitude1 = d1.GetMagnitudeSquared(); var p1 = (0.0 < sMin) ? a + (d0.GetScaled(sMin)) : a; var p2 = a + (d0.GetScaled(sMax < 1.0 ? sMax : 1.0)); var pd = p2 - p1; s1 = d0.Dot(p1 - a) / squareMagnitude0; s2 = s1 + (d0.Dot(pd) / squareMagnitude0); var t1 = d1.Dot(p1 - c) / squareMagnitude1; resultA = new PointResult(p1, s1, t1); resultB = new PointResult(p2, s2, t1 + (d1.Dot(pd) / squareMagnitude1)); } return new SegmentResult(resultA, resultB); }
public List<int> dotProductExtract(List<Vector2> xCart, double bAngle) { List<double> bAngles1 = new List<double>(); List<double> bAngles2 = new List<double>(); List<int> iCorners = new List<int>(); for (int i = 2; i < ibook.Count - 2; i++) { Vector2 a = new Vector2(xCart[i + 1].Y - xCart[i].Y, xCart[i + 1].X - xCart[i].X); Vector2 b = new Vector2(xCart[i - 1].Y - xCart[i].Y, xCart[i - 1].X - xCart[i].X); Vector2 c = new Vector2(xCart[i + 2].Y - xCart[i].Y, xCart[i + 2].X - xCart[i].X); Vector2 d = new Vector2(xCart[i - 2].Y - xCart[i].Y, xCart[i - 2].X - xCart[i].X); bAngles1.Add(Math.Acos(a.Dot(b) / (a.Length * b.Length))); bAngles2.Add(Math.Acos(c.Dot(d) / (c.Length * d.Length))); if ((bAngles1[i - 2] < bAngle) && (bAngles2[i - 2] < bAngle)) iCorners.Add(i); } return iCorners; }
public void BuildProbabilities( double _CameraTheta, ParametrizedSpace _Probas ) { Vector ViewTS = new Vector( Math.Sin( _CameraTheta ), 0.0, Math.Cos( _CameraTheta ) ); Vector LightTS = new Vector( 0, 0, 0 ); double L = 2.0 * _CameraTheta / Math.PI; Vector2 Center = new Vector2( 0, L ); // We choose the center to be (0,ThetaD0) // Vector2 U = new Vector2( L, -L ); // U direction goes down to (ThetaH0,0) Vector2 U = new Vector2( 0.5 / L, -0.5 / L ); // U direction goes down to (ThetaH0,0) // Vector2 V = new Vector2( 1-L, 1-L ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) // Vector2 V = new Vector2( 0.5 / (1-L), 0.5 / (1-L) ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) Vector2 V = new Vector2( 1.0 / (1-L), 1.0 / (1-L) ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) double Normalizer = 100.0 / (SAMPLES_COUNT_PHI * SAMPLES_COUNT_THETA); Vector2 ST = new Vector2( 0, 0 ); Vector2 Delta = new Vector2( 0, 0 ); Vector2 UV = new Vector2( 0, 0 ); _Probas.Clear(); int ScaleAngle = Math.Min( 89, (int) (90 * L) ); for ( var Y=0; Y < SAMPLES_COUNT_PHI; Y++ ) { var PhiL = Math.PI * ((double) Y / SAMPLES_COUNT_PHI - 0.5); var CosPhiL = Math.Cos( PhiL ); var SinPhiL = Math.Sin( PhiL ); for ( var X=0; X < SAMPLES_COUNT_THETA; X++ ) { // var ThetaL = 0.5 * Math.PI * X / SAMPLES_COUNT_THETA; var ThetaL = Math.Asin( Math.Sqrt( (double) X / SAMPLES_COUNT_THETA ) ); // Account for cosine weight of samples var CosThetaL = Math.Cos( ThetaL ); var SinThetaL = Math.Sin( ThetaL ); LightTS.x = SinThetaL * SinPhiL; LightTS.y = SinThetaL * CosPhiL; LightTS.z = CosThetaL; var Half = (ViewTS + LightTS).Normalize(); var ThetaH = Math.Acos( Half.z ); var ThetaD = Math.Acos( ViewTS.Dot( Half ) ); // Normalize in ST space ST.x = 2*ThetaH/Math.PI; ST.y = 2*ThetaD/Math.PI; // Transform into UV space Delta = ST - Center; UV.x = Delta.Dot( U ); UV.y = Delta.Dot( V ); // Find scaling factor int ScaleX = Math.Max( 0, Math.Min( PROBA_ARRAY_SIZE-1, (int) (PROBA_ARRAY_SIZE * UV.x) ) ); double Scale = m_Scales[ScaleAngle,ScaleX]; UV.y *= Scale; _Probas.Accumulate( UV, Normalizer ); } } }
/// <summary> /// Performs deviation analysis on a test's data. /// </summary> private void Trace(int t, int dt, short x, short y, short p) { /* * Assumptions: * TestData origin matches Path origin. * Axis follows standard .NET drawing conventions: * X increases from left to right * Y increases from top to bottom */ double MinDeviation = double.PositiveInfinity; Vector2 SamplePoint = new Vector2(x, y), MinDistance = new Vector2(double.PositiveInfinity, double.PositiveInfinity); foreach(PointF[] subpath in Paths) { for(int k = 1; k < subpath.Length; k++) { //compute the distance vector to the current line segment Vector2 Distance = PointLineDistance(subpath[k - 1], subpath[k], SamplePoint); double DistanceNorm = Distance.Norm(); if(DistanceNorm < MinDeviation) { MinDeviation = DistanceNorm; MinDistance = Distance; } } } //we consider the intended point as the point nearest the sample this[AnalysisMetric.Deviation].Add(MinDeviation); //compute the sign of the cos(theta) //here theta is the angle between distance vector and mean-origin vector switch(Math.Sign(MinDistance.Dot(-1 * SamplePoint))) { case -1: //pi/2 < theta < pi; distance vector points away from origin this[AnalysisMetric.InnerDeviation].Add(MinDeviation); break; case 1: //0 < theta < pi/2; distance vector points towards origin this[AnalysisMetric.OuterDeviation].Add(MinDeviation); break; } }