Beispiel #1
0
        static int Solve4D(string[] initialState)
        {
            int width  = 21;
            int height = 21;
            int depth  = 21;
            int wdim   = 21;

            var current = new Matrix4D <char>(width, height, depth, wdim, Enumerable.Repeat('.', width * height * depth * wdim).ToArray());
            int cx      = 6;
            int cy      = 6;
            int cz      = 10;
            int cw      = 10;

            for (int y = 0; y < initialState.Length; y++)
            {
                for (int x = 0; x < initialState[0].Length; x++)
                {
                    current[cx + x, cy + y, cz, cw] = initialState[y][x];
                }
            }

            var next = current.Clone();

            for (int i = 1; i <= 6; i++)
            {
                for (int w = 0; w < wdim; w++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        for (int y = 0; y < height; y++)
                        {
                            for (int x = 0; x < width; x++)
                            {
                                var state           = current[x, y, z, w];
                                int activeNeighbors = CountNeighbors(current, x, y, z, w);
                                if (state == '#')
                                {
                                    next[x, y, z, w] = (activeNeighbors == 2 || activeNeighbors == 3) ? '#' : '.';
                                }
                                else
                                {
                                    next[x, y, z, w] = activeNeighbors == 3 ? '#' : '.';
                                }
                            }
                        }
                    }
                }
                var tmp = current;
                current = next;
                next    = tmp;
            }
            return(current.Array.Count(c => c == '#'));
        }
Beispiel #2
0
        /// <summary>
        /// This calculates the 4 vertices of a general (but finite) Goursat Tetrahedron.  Result is in the ball model.
        ///
        /// The method comes from the dissertation "Hyperbolic polyhedra: volume and scissors congruence",
        /// by Yana Zilberberg Mohanty, section 2.4, steps 1-5.
        ///
        /// A,B,C are the three dihedral angles surrounding a vertex.
        /// A_,B_,C_ are the three oppoite dihedral angles.
        /// </summary>
        public static Vector3D[] GoursatTetrahedron(double A, double B, double C, double A_, double B_, double C_)
        {
            // Step 1: Construct Gram matrix with reversed rows/columns.
            // NOTE: The sign of the diagonal in the paper was incorrect.
            double pi = Math.PI;

            double[,] gramMatrixData = new double[, ]
            {
                { -1, Math.Cos(pi / A_), Math.Cos(pi / B_), Math.Cos(pi / C) },
                { Math.Cos(pi / A_), -1, Math.Cos(pi / C_), Math.Cos(pi / B) },
                { Math.Cos(pi / B_), Math.Cos(pi / C_), -1, Math.Cos(pi / A) },
                { Math.Cos(pi / C), Math.Cos(pi / B), Math.Cos(pi / A), -1 },
            };
            Matrix4D gramMatrix = new Matrix4D(gramMatrixData);

            gramMatrix *= -1;
            Matrix4D identity = Matrix4D.Identity();

            // Step 2: Gram-Schmidt.
            Matrix4D W = GramSchmidt(identity, gramMatrix);

            // Step 3: Divide 4th row by i (already effectively done in our Gram-Schmidt routine below), and reverse order of rows.
            Matrix4D W_ = ReverseRows(W);

            // Step 4
            Matrix4D D = identity.Clone();

            D[0, 0] = -1;
            Matrix4D U = Matrix4D.Transpose(D * W_);

            // Step 5
            Matrix4D U_ = ReverseRows(U);

            for (int i = 0; i < 4; i++)
            {
                MinkowskiNormalize(U_[i]);
            }

            // Now move from the hyperboloid model to the ball.
            List <Vector3D> result = new List <Vector3D>();

            for (int i = 0; i < 4; i++)
            {
                result.Add(HyperboloidToBall(U_[i]));
            }
            return(result.ToArray());
        }
Beispiel #3
0
        public static Matrix4D GramSchmidt(Matrix4D input, Matrix4D innerProductValues)
        {
            Matrix4D result = input.Clone();

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    Vector3D iVec  = result[i];
                    Vector3D jVec  = result[j];
                    double   inner = innerProductValues[i].Dot(jVec);
                    iVec     -= inner * jVec;
                    result[i] = iVec;
                }

                // Normalize.  We don't use Vector3D normalize because we might have timelike vectors.
                double mag2 = innerProductValues[i].Dot(result[i]);
                double abs  = mag2 < 0 ? -Math.Sqrt(-mag2) : Math.Sqrt(mag2);
                result[i].Divide(abs);
            }

            return(result);
        }