static bool OnLine(Vertex a, Vertex b, Vertex c) { Vector vA = a.Position; Vector vB = b.Position; Vector vC = c.Position; double orientation = (vB.x - vA.x) * (vC.y - vA.y) - (vB.y - vA.y) * (vC.x - vA.x); double max = Math.Max(vA.AbsSquare(), Math.Max(vB.AbsSquare(), vC.AbsSquare())); if (Math.Abs(orientation) < accuracy * max) { return(true); } else { return(false); } }
/// <summary> /// Checks for equality by using relative error /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="accuracy"></param> /// <param name="zeroAccuracy"></param> /// <returns></returns> public static bool IsEqual(Vector a, Vector b, double accuracy = 1e-10, double zeroAccuracy = 1e-12) { double absA = a.AbsSquare(); double absB = b.AbsSquare(); double max = Math.Max(absA, absB); double diff = (a - b).AbsSquare(); if (absA == 0 || absB == 0 || max < zeroAccuracy * zeroAccuracy) { return(diff < zeroAccuracy * zeroAccuracy); } else { if (diff < max * accuracy * accuracy) { return(true); } else { return(false); } } }
/// <summary> /// Constructs a new state vector using data given in primitive /// variables /// </summary> /// <param name="material"> /// The material/fluid associated with the represented state. /// </param> /// <param name="density"><see cref="Density"/></param> /// <param name="velocity"><see cref="Velocity"/></param> /// <param name="pressure"><see cref="Pressure"/></param> /// <returns></returns> public static StateVector FromPrimitiveQuantities(Material material, double density, Vector velocity, double pressure) { Debug.Assert(velocity.Dim > 0); double MachScaling = material.EquationOfState.HeatCapacityRatio * material.MachNumber * material.MachNumber; StateVector state = new StateVector( material, density, density * velocity, material.EquationOfState.GetInnerEnergy(density, pressure) + 0.5 * MachScaling * density * velocity.AbsSquare()); Debug.Assert(state.Dimension > 0); Debug.Assert(state.Dimension == velocity.Dim); return(state); }
/// <summary> /// Intersection of line <paramref name="S1"/>--<paramref name="S2"/> and <paramref name="E1"/>--<paramref name="E2"/> /// </summary> /// <param name="S1"></param> /// <param name="S2"></param> /// <param name="E1"></param> /// <param name="E2"></param> /// <param name="alpha1"> /// coordinate of <paramref name="I"/> on the line <paramref name="S1"/>--<paramref name="S2"/> /// </param> /// <param name="alpha2"> /// coordinate of <paramref name="I"/> on the line <paramref name="E1"/>--<paramref name="E2"/> /// </param> /// <param name="I"></param> /// <returns></returns> public static bool ComputeIntersection(Vector S1, Vector S2, Vector E1, Vector E2, out double alpha1, out double alpha2, out Vector I) { if (S1.Dim != 2) { throw new ArgumentException("spatial dimension mismatch."); } if (S2.Dim != 2) { throw new ArgumentException("spatial dimension mismatch."); } if (E1.Dim != 2) { throw new ArgumentException("spatial dimension mismatch."); } if (E2.Dim != 2) { throw new ArgumentException("spatial dimension mismatch."); } Vector S12 = S2 - S1; Vector E12 = E2 - E1; var P_S12 = AffineManifold.FromPoints(S1, S2); var P_E12 = AffineManifold.FromPoints(E1, E2); double parallel = S12[0] * E12[1] - S12[1] * E12[0]; double relParallel = parallel * parallel / (S12.AbsSquare() * E12.AbsSquare()); if (Math.Abs(relParallel) <= 1e-20) { alpha1 = P_S12.PointDistance(E1); alpha1 /= E12.Abs(); alpha2 = double.PositiveInfinity; I = new Vector(double.PositiveInfinity, double.PositiveInfinity); return(false); } //S12.Normalize(); //E12.Normalize(); I = AffineManifold.Intersect2D(P_S12, P_E12); Vector IS1 = I - S2; Vector IE1 = I - E2; Vector IS2 = I - S1; Vector IE2 = I - E1; Vector IS; bool flip_1; if (IS1.AbsSquare() > IS2.AbsSquare()) { IS = IS1; flip_1 = true; } else { IS = IS2; flip_1 = false; } Vector IE; bool flip_2; if (IE1.AbsSquare() > IE2.AbsSquare()) { IE = IE1; flip_2 = true; } else { IE = IE2; flip_2 = false; } Debug.Assert((S12.AngleTo(IS).Abs() <= 1.0e-5) || ((S12.AngleTo(IS).Abs() - Math.PI).Abs() <= 1.0e-5)); Debug.Assert((E12.AngleTo(IE).Abs() <= 1.0e-5) || ((E12.AngleTo(IE).Abs() - Math.PI).Abs() <= 1.0e-5)); alpha1 = (S12 * IS) / S12.AbsSquare(); alpha2 = (E12 * IE) / E12.AbsSquare(); if (flip_1) { alpha1 = 1 + alpha1; } if (flip_2) { alpha2 = 1 + alpha2; } return(true); }