Beispiel #1
0
        /**
         * Methode die het punt bepaald waarop een ray, gerepresenteerd door a en b in een array, in een face f.
         * De vertices van de Face f zitten in de model waar f in zit.
         */
        static double RayTriangleIntersection(ref unitVector direction, ref Model3D model, ref Face f)
        {
            double r = 0.0;
            Vec3D[] v = model.vertices;

            Vec3D h = f.normal;// v[f.vertices[1]].subtract(v[f.vertices[0]]).cross(v[f.vertices[2]].subtract(v[f.vertices[0]]));
            if (h.length() > double.Epsilon)
            {
                Vec3D normal = f.normal.normalize();
                //normalize the normal, then dot it with the direction vector
                double NU = System.Math.Abs(normal.dot(direction.vector));
                if (NU > double.Epsilon)
                {
                    double d = (normal.dot(v[f.vertices[0]])) / NU;
                    if (d > r)
                    {
                        Vec3D P = direction.vector.times(d);
                        //is P on the triangle?
                        if ((v[f.vertices[0]].subtract(P).cross(v[f.vertices[1]].subtract(P))).dot(f.normal) >= 0 &&
                            (v[f.vertices[1]].subtract(P).cross(v[f.vertices[2]].subtract(P))).dot(f.normal) >= 0 &&
                            (v[f.vertices[2]].subtract(P).cross(v[f.vertices[0]].subtract(P))).dot(f.normal) >= 0)
                            return d;
                    }

                }
            }

            //the ray will not intersect with the triangle
            return double.NaN;
        }
Beispiel #2
0
        /**
         * Methode die het punt bepaald waarop een ray, gerepresenteerd door a en b in een array, in een face f.
         * De vertices van de Face f zitten in de model waar f in zit.
         */
        static double RayTriangleIntersection2(ref unitVector direction, ref Model3D model, ref Face f)
        {
            double r = 0.0;
            double d = 0.0;
            Vec3D[] v = model.vertices;
            Vec3D u = direction.vector;

            Vec3D A = v[f.vertices[0]];
            Vec3D B = v[f.vertices[1]];
            Vec3D C = v[f.vertices[2]];
            Vec3D CA = A.subtract(C);
            Vec3D CB = B.subtract(C);

            Vec3D p = u.cross(CB);
            double det = CA.dot(p);
            if (det > double.Epsilon)
            {
                double AlphaS = C.times(-1.0).dot(p);
                if (AlphaS >= 0 && AlphaS <= det)
                {
                    Vec3D q = CA.cross(C);
                    double BetaS = u.dot(q);
                    if (BetaS >= 0 && AlphaS + BetaS <= det)
                        d = (CB.dot(q)) / det;
                }
            }
            else if(det < 0-Double.Epsilon)
            {
                double AlphaS = C.times(-1).dot(p);
                if (AlphaS <= 0 && AlphaS >= det)
                {
                    Vec3D q = CA.cross(C);
                    double BetaS = u.dot(q);
                    if (BetaS <= 0 && AlphaS + BetaS >= det)
                        d = (CB.dot(q)) / det;
                }
            }

            if (d > r)
                r = d;
            //the ray will not intersect with the triangle
            return r;
        }
Beispiel #3
0
        private static double getExtendOneVector(ref Model3D model, ref unitVector direction)
        {
            double tempExtend = 0.0;
            for (int i = 0; i < model.faces.Length; i++)
            {
                Face f = model.faces[i];
                double extend = RayTriangleIntersection2(ref direction, ref model, ref f);
                if (extend > tempExtend)
                    tempExtend = extend;
            }

            return tempExtend;
        }
Beispiel #4
0
        public static double[] SFFT(double[] data, unitVector[] ds)
        {
            //B^2 complex coefficients Flm in the range 0 (<= |m| <= l <= B)
            //extract the descriptor for k! the paper says 29 is good, or use the rotation invariant feature vector

            double[] rcoeffs = new double[B * B];   //(double*)malloc(sizeof(double) * (bw * bw));
            double[] icoeffs = new double[B * B];   //(double*)malloc(sizeof(double) * (bw * bw));
            double[] rdata = data;                  //(double*)malloc(sizeof(double) * (size * size));
            double[] idata = new double[4 * B * B];     //(double*)malloc(sizeof(double) * (size * size));
            double[] rdata2 = new double[4 * B * B];                //(double*)malloc(sizeof(double) * (size * size));
            double[] idata2 = new double[4 * B * B];     //(double*)malloc(sizeof(double) * (size * size));
            //idata = 0.0
            for (int i = 0; i < idata.Length; i++)
            {
                idata[i] = 0.0;
            }

            Console.WriteLine("Starting SFFT");
            DateTime startTime1 = DateTime.Now;

            try
            {
                calcCoeff(B, B, rdata, idata, rcoeffs, icoeffs);

                //if you wanna compute the real model again
                inverseTransform(B, B, rcoeffs, icoeffs, rdata2, idata2);
            }
            catch (DllNotFoundException e)
            {
                Console.WriteLine(e.StackTrace + "\n");
                Console.WriteLine("DLL not found.");
                Application.Exit();
            }
            //if you wanna compute the real model again

            Vec3D[] points = new Vec3D[4*B*B];
            for (int i = 0; i < rdata2.Length; i++)
            {
                int b = i % B2;
                int a = (i / B2);
                points[i] = ds[B2*b+a].vector.times(rdata2[i]);
            }
            Random test = new Random();
            FileWriter.WritePointCloudObj(points, "pointcloud" + test.Next(100));

            DateTime stopTime1 = DateTime.Now;
            TimeSpan duration1 = stopTime1 - startTime1;
            Console.WriteLine("SFFT duration: {0}", duration1.TotalSeconds);
            Console.WriteLine("Done SFFT");

            double[] fv = new double[B];
            /*
            int k = 29;
            double[] fv2 = new double[k * (k + 1) / 2 + 1];
            int total = 0;
            for (int l = 0; l < k; l++)
            {
                for (int m = 0; m < l; m++)
                {
                    int index = getCoeffIndex(m, l);
                    double mag = System.Math.Sqrt(rcoeffs[index] * rcoeffs[index] + icoeffs[index] * icoeffs[index]);
                    if(m == 0)
                    {
                        fv2[total] = mag/2;
                        total++;
                    }
                    else
                    {
                        fv2[total] = mag;
                        total++;
                    }

                }
            }

            return fv2; */

            for (int l = 0; l < B; l++)
            {
                double result = 0;
                for (int m = 0 - l; m <= l; m++)
                {
                    int index = getCoeffIndex(m, l);
                    result += rcoeffs[index] * rcoeffs[index] + icoeffs[index] * icoeffs[index];
                }
                fv[l] = System.Math.Sqrt(result);
            }

            return fv;
        }
Beispiel #5
0
        static double[] getExtendBruteForce(ref Model3D model, ref unitVector[] ds)
        {
            double[] extends = new double[4 * B * B];

            //initialize all values to 0
            for (int q = 0; q < extends.Length; q++)
                extends[q] = 0.0;

            int counter = 0;

            for (int k = 0; k < model.faces.Length; k++)
            {
                Face f = model.faces[k];

                for (int i = 0; i < ds.Length; i++)
                {
                    unitVector temp = ds[i];
                    double extend = RayTriangleIntersection2(ref temp, ref model, ref f);
                    counter++;
                    if (double.IsNaN(extend))
                    {
                       // System.Console.WriteLine("Did not hit. a: {0} b: {1}", temp.a, temp.b);
                        continue;
                    }
                    int temporary = (temp.a * 2 * B) + temp.b;
                    if (extends[temporary] < extend)
                        extends[temporary] = extend;
            /*                Console.WriteLine("Extends {0}:\textend: {1},\tphi: {2},\ttheta: {3},\t" +
                                          "minPhi: {4},\tmaxPhi: {5},\tminTheta: {6},\tmaxTheta: {7},\t" +
                                          "minPhiIndexValue: {8},\tmaxPhiIndexValue: {9},\tminThetaIndexValue: {10},\tmaxThetaIndexValue: {11}",
                                          temporary, extend, temp.phi, temp.theta, 0, System.Math.PI*2,
                                          0, System.Math.PI, 0, System.Math.PI * 2,
                                          0, System.Math.PI);
              */        }
            }

            return extends;
        }
Beispiel #6
0
        static double[] getExtend(ref Model3D model, ref unitVector[] ds)
        {
            double[] extends = new double[4*B*B];

            //initialize all values to 0
            for(int q = 0; q < extends.Length; q++)
                extends[q] = 0.0;

            int counter = 0;

            for(int k=0; k < model.faces.Length; k++)
            {
                Face f = model.faces[k];
                double[] phiTheta = getMinMaxPhiTheta(ref f, ref model.vertices,ref model);
                double minPhi = phiTheta[0];
                double minTheta = phiTheta[1];
                double maxPhi = phiTheta[2];
                double maxTheta = phiTheta[3];

                double searchPhi;
                if (minPhi < 0)
                    searchPhi = minPhi + (2 * System.Math.PI);
                else
                    searchPhi = minPhi;

                int minPhiIndex = BinSearchPhi(ref ds, searchPhi, 0, ds.Length - 1, false);
                while (minPhiIndex > 0 && ds[minPhiIndex - 1].phi == ds[minPhiIndex].phi)
                    minPhiIndex--;

                if (maxPhi < 0)
                    searchPhi = maxPhi + 2 * System.Math.PI;
                else
                    searchPhi = maxPhi;

                int maxPhiIndex = BinSearchPhi(ref ds, maxPhi, 0, ds.Length - 1, true);
                while (maxPhiIndex < ds.Length-1 && ds[maxPhiIndex + 1].phi == ds[maxPhiIndex].phi)
                    maxPhiIndex++;

                //min en max van de theta zijn onveranderlijk over de subset in phi. Dit vanwege
                //de sortering over eerst phi en vervolgens theta, waardoor de opeenvolging altijd hetzelfde is.
                int minThetaIndex = BinSearchTheta(ref ds, minTheta, minPhiIndex, minPhiIndex + B2, false);
                minThetaIndex -= minPhiIndex; // maakt de index relatief ten opzicht van de phiIndex

                int maxThetaIndex = BinSearchTheta(ref ds, maxTheta, minPhiIndex, minPhiIndex + B2, true);
                maxThetaIndex -= minPhiIndex;

                int thetaRange = maxThetaIndex - minThetaIndex;

                int range = System.Math.Abs(maxPhiIndex - minPhiIndex) / B2;

                for (int i = 0; i <= range; i++)
                {
                    for (int j = 0; j <= thetaRange; j++)
                    {
                        int index = (minPhiIndex + i * B2 + minThetaIndex + j) % ds.Length;
                        //Modulo vanwege dat als maxPhi groter is dan PI het eigenlijk negatief is, daarom moet er over het einde van de array worden doorgelopen.
                        unitVector temp = ds[index];
                        double extend = RayTriangleIntersection2(ref temp, ref model, ref f);
                        counter++;
                        if (extend == 0.0)
                        {
                           // System.Console.WriteLine("Did not hit. a: {0} b: {1}",temp.a, temp.b);
                            continue;
                        }
                        int temporary = (temp.a * 2 * B) + temp.b;
                        if(extends[temporary] < extend)
                            extends[temporary] = extend;

            /*                        Console.WriteLine("Extends {0}: \textend: {1},\tphi: {2},\ttheta: {3},\t" +
                                          "minPhi: {4},\tmaxPhi: {5},\tminTheta: {6},\tmaxTheta: {7},\t" +
                                          "minPhiIndexValue: {8},\tmaxPhiIndexValue: {9},\tminThetaIndexValue: {10},\tmaxThetaIndexValue: {11}",
                                          temporary, extend, temp.phi, temp.theta, minPhi, maxPhi,
                                          minTheta, maxTheta, ds[minPhiIndex + minThetaIndex].phi, ds[minPhiIndex + (range - 1) * B2 + minThetaIndex].phi,
                                          ds[minPhiIndex + minThetaIndex].theta, ds[minPhiIndex + (range - 1) * B2 + minThetaIndex].theta);
              */                }
                }
            }

            System.Console.WriteLine(counter);

            return extends;
        }
Beispiel #7
0
        //creates a sorted array (in phi and theta) of direction vectors
        static unitVector[] getDirections()
        {
            unitVector[] direct = new unitVector[4 * B * B];
            int total = 0;

            double tempTheta = (System.Math.PI * 2) / (4 * B), tempTheta2 = System.Math.PI/(4*B);
            double tempPhi = System.Math.PI / B;

            for (int a = 0; a < B2; a++)
                for (int b = 0; b < B2; b++)
                {
                    double theta, phi;
                    theta = a * tempTheta + tempTheta2;
                    phi = b * tempPhi; //equals 2bPI/2B
                    direct[total] = new unitVector(phi, theta, a, b,
                                                    new Vec3D(System.Math.Cos(phi) * System.Math.Sin(theta),
                                                                System.Math.Sin(phi) * System.Math.Sin(theta),
                                                                System.Math.Cos(theta)));
                    total++;
                }
            return direct;
        }
Beispiel #8
0
        //do all the important stuff :-)
        static double[] extractFeatureVector(ref Model3D model, ref unitVector[] ds)
        {
            //bruteforce
               // double[] extends2 = getExtendBruteForce(ref model, ref ds);

            //optimized
            double[] extends = getExtend(ref model, ref ds);

            //because of a error with the calculation of phi because of Atan2, the 0 values are recalculated
            for (int i = 0; i < extends.Length; i++)
            {
                if (extends[i] == 0.0)
                {
                    int b = i % B2;
                    int a = (i / B2);
                    extends[i] = getExtendOneVector(ref model, ref ds[B2 * b + a]);
                }
            }

            double[] feature = SFFT(extends, ds);
            return feature;
        }
Beispiel #9
0
        static int BinSearchTheta(ref unitVector[] ds, double value, int low, int high, bool max)
        {
            if (high == low)
                return low;

            if (high < low)
                if (max)
                    return low;
                else
                    return high;

            int mid = low + (int)((high - low) / 2);
            if (ds[mid].theta > value)
                return BinSearchTheta(ref ds, value, low, mid - 1, max);
            else if (ds[mid].theta < value)
                return BinSearchTheta(ref ds, value, mid + 1, high, max);
            else
                return mid; // found
        }