예제 #1
0
        private void cmd_rotate(params object[] param)
        {
            int    handle = (int)param[0];
            double theta  = (double)param[1];

            polygon_lib[handle].trans = Mat3x3.RotateCounterClockwise(theta) * polygon_lib[handle].trans;
        }
예제 #2
0
 public void ResetTransformLib()
 {
     for (int i = 0; i < polygon_lib.Count; i++)
     {
         polygon_lib[i].trans = Mat3x3.Eye();
     }
 }
예제 #3
0
        private void cmd_scale(params object[] param)
        {
            int    handle  = (int)param[0];
            double scale_x = (double)param[1];
            double scale_y = (double)param[2];

            polygon_lib[handle].trans = Mat3x3.Scale(scale_x, scale_y) * polygon_lib[handle].trans;
        }
예제 #4
0
        private void cmd_translate(params object[] param)
        {
            int    handle      = (int)param[0];
            double translate_x = (double)param[1];
            double translate_y = (double)param[2];

            polygon_lib[handle].trans = Mat3x3.Translate(translate_x, translate_y) * polygon_lib[handle].trans;
        }
예제 #5
0
        public static Ngons Clone(this Ngons polys, Mat3x3 T)
        {
            Ngons clone = new Ngons(polys.Count);

            for (int i = 0; i < polys.Count; i++)
            {
                clone.Add(polys[i].Clone(T));
            }
            return(clone);
        }
예제 #6
0
        public static Ngon Clone(this Ngon poly, Mat3x3 T)
        {
            Ngon clone = new Ngon(poly.Count);

            for (int i = 0; i < poly.Count; i++)
            {
                clone.Add(T * poly[i]);
            }
            return(clone);
        }
예제 #7
0
        public int AddCanvasFitPolygon(IntRect canvas, int pattern_handle)
        {
            Ngon B = polygon_lib[pattern_handle].GetTransformedPoly()[0];

            Ngon C = GeomUtility.CanFitInsidePolygon(canvas, B);

            polygon_lib.Add(new PolyRef()
            {
                poly = new Ngons()
                {
                    C
                }, trans = Mat3x3.Eye()
            });
            return(polygon_lib.Count - 1);
        }
예제 #8
0
        public static Mat3x3 operator *(Mat3x3 A, Mat3x3 B)
        {
            Mat3x3 I = new Mat3x3();

            I.x11 = A.x11 * B.x11 + A.x12 * B.x21 + A.x13 * B.x31;
            I.x12 = A.x11 * B.x12 + A.x12 * B.x22 + A.x13 * B.x32;
            I.x13 = A.x11 * B.x13 + A.x12 * B.x23 + A.x13 * B.x33;
            I.x21 = A.x21 * B.x11 + A.x22 * B.x21 + A.x23 * B.x31;
            I.x22 = A.x21 * B.x12 + A.x22 * B.x22 + A.x23 * B.x32;
            I.x23 = A.x21 * B.x13 + A.x22 * B.x23 + A.x23 * B.x33;
            I.x31 = A.x31 * B.x11 + A.x32 * B.x21 + A.x33 * B.x31;
            I.x32 = A.x31 * B.x12 + A.x32 * B.x22 + A.x33 * B.x32;
            I.x33 = A.x31 * B.x13 + A.x32 * B.x23 + A.x33 * B.x33;

            return(I);
        }
예제 #9
0
        public static Mat3x3 Scale(double scale_x, double scale_y, double scale_z = 1.0)
        {
            Mat3x3 I = new Mat3x3();

            I.x11 = scale_x;
            I.x12 = 0;
            I.x13 = 0;
            I.x21 = 0;
            I.x22 = scale_y;
            I.x23 = 0;
            I.x31 = 0;
            I.x32 = 0;
            I.x33 = scale_z;

            return(I);
        }
예제 #10
0
        public static Mat3x3 Translate(double t_x, double t_y)
        {
            Mat3x3 I = new Mat3x3();

            I.x11 = 1;
            I.x12 = 0;
            I.x13 = t_x;

            I.x21 = 0;
            I.x22 = 1;
            I.x23 = t_y;
            I.x31 = 0;
            I.x32 = 0;
            I.x33 = 1;

            return(I);
        }
예제 #11
0
        public Mat3x3 Inverse()
        {
            double D = Determinant();

            Mat3x3 I = new Mat3x3();

            I.x11 = Det2x2(x22, x23, x32, x33) / D;
            I.x12 = Det2x2(x13, x12, x33, x32) / D;
            I.x13 = Det2x2(x12, x13, x22, x23) / D;
            I.x21 = Det2x2(x23, x21, x33, x31) / D;
            I.x22 = Det2x2(x11, x13, x31, x33) / D;
            I.x23 = Det2x2(x13, x11, x23, x21) / D;
            I.x31 = Det2x2(x21, x22, x31, x32) / D;
            I.x32 = Det2x2(x12, x11, x32, x31) / D;
            I.x33 = Det2x2(x11, x12, x21, x22) / D;

            return(I);
        }
예제 #12
0
        public static Mat3x3 RotateCounterClockwise(double t)
        {
            Mat3x3 T = new Mat3x3();

            double c = Math.Cos(t);
            double s = Math.Sin(t);

            T.x11 = c;
            T.x12 = -s;
            T.x13 = 0;
            T.x21 = s;
            T.x22 = c;
            T.x23 = 0;
            T.x31 = 0;
            T.x32 = 0;
            T.x33 = 1;

            return(T);
        }
예제 #13
0
        public int AddMinkowskiSum(int subj_handle, int pattern_handle, NFPQUALITY quality, bool flip_pattern, int set_at = -1)
        {
            Ngons A = polygon_lib[subj_handle].GetTransformedPoly();
            Ngons B = polygon_lib[pattern_handle].GetTransformedPoly();

            Ngons   C    = GeomUtility.MinkowskiSum(B[0], A, quality, flip_pattern);
            PolyRef pref = new PolyRef()
            {
                poly = C, trans = Mat3x3.Eye()
            };

            if (set_at < 0)
            {
                polygon_lib.Add(pref);
            }
            else
            {
                polygon_lib[set_at] = pref;
            }

            return(set_at < 0 ? polygon_lib.Count - 1 : set_at);
        }
예제 #14
0
        private void cmd_optimal_rotation(int handle)
        {
            Ngon hull = polygon_lib[handle].GetTransformedPoly()[0];
            int  n    = hull.Count;

            double best_t    = 0;
            int    best      = 0;
            long   best_area = long.MaxValue;
            bool   flip_best = false;

            for (int i = 0; i < n; i++)
            {
                double t = GeomUtility.AlignToEdgeRotation(hull, i);

                Mat3x3 rot = Mat3x3.RotateCounterClockwise(t);

                Ngon clone = hull.Clone(rot);

                IntRect bounds = GeomUtility.GetBounds(clone);
                long    area   = bounds.Area();
                double  aspect = bounds.Aspect();

                if (area < best_area)
                {
                    best_area = area;
                    best      = i;
                    best_t    = t;
                    flip_best = aspect > 1.0;
                }
            }

            double   flip   = flip_best ? Math.PI * 0.5 : 0;
            IntPoint around = hull[best];

            cmd_translate(handle, (double)-around.X, (double)-around.Y);
            cmd_rotate(handle, best_t + flip);
            cmd_translate(handle, (double)around.X, (double)around.Y);
        }
예제 #15
0
        /// <summary>
        /// Append a set triangulated polygons to the nester and get handles for each point to the correp. polygon island
        /// </summary>
        /// <param name="points"></param>
        /// <param name="tris"></param>
        /// <returns></returns>
        public int[] AddPolygons(IntPoint[] points, int[] tris, double miter_distance = 0.0)
        {
            // from points to clusters of tris
            int[] poly_map = new int[points.Length];
            for (int i = 0; i < poly_map.Length; i++)
            {
                poly_map[i] = -1;
            }

            HashSet <int>[] graph = new HashSet <int> [points.Length];
            for (int i = 0; i < graph.Length; i++)
            {
                graph[i] = new HashSet <int>();
            }
            for (int i = 0; i < tris.Length; i += 3)
            {
                int t1 = tris[i];
                int t2 = tris[i + 1];
                int t3 = tris[i + 2];

                graph[t1].Add(t2);
                graph[t1].Add(t3);
                graph[t2].Add(t1);
                graph[t2].Add(t3);
                graph[t3].Add(t1);
                graph[t3].Add(t2);
            }

            if (graph.Any(p => p.Count == 0))
            {
                throw new Exception("No singular vertices should exist on mesh");
            }

            int[] clust_ids = new int[points.Length];

            HashSet <int> unmarked  = new HashSet <int>(Enumerable.Range(0, points.Length));
            int           clust_cnt = 0;

            while (unmarked.Count > 0)
            {
                Queue <int> open  = new Queue <int>();
                int         first = unmarked.First();
                unmarked.Remove(first);
                open.Enqueue(first);
                while (open.Count > 0)
                {
                    int c = open.Dequeue();
                    clust_ids[c] = clust_cnt;
                    foreach (int n in graph[c])
                    {
                        if (unmarked.Contains(n))
                        {
                            unmarked.Remove(n);
                            open.Enqueue(n);
                        }
                    }
                }

                clust_cnt++;
            }

            Ngons[] clusters = new Ngons[clust_cnt];
            for (int i = 0; i < tris.Length; i += 3)
            {
                int clust = clust_ids[tris[i]];
                if (clusters[clust] == null)
                {
                    clusters[clust] = new Ngons();
                }

                IntPoint p1 = points[tris[i]];
                IntPoint p2 = points[tris[i + 1]];
                IntPoint p3 = points[tris[i + 2]];

                clusters[clust].Add(new Ngon()
                {
                    p1, p2, p3
                });
            }

            List <Ngons> fulls = new List <Ngons>();

            for (int i = 0; i < clust_cnt; i++)
            {
                Ngons cl = clusters[i];

                Clipper c = new Clipper();
                foreach (Ngon n in cl)
                {
                    c.AddPath(n, PolyType.ptSubject, true);
                }

                Ngons full = new Ngons();
                c.Execute(ClipType.ctUnion, full, PolyFillType.pftNonZero);
                full = Clipper.SimplifyPolygons(full, PolyFillType.pftNonZero);

                if (miter_distance > 0.00001)
                {
                    Ngons         full_miter = new Ngons();
                    ClipperOffset co         = new ClipperOffset();
                    co.AddPaths(full, JoinType.jtMiter, EndType.etClosedPolygon);
                    co.Execute(ref full_miter, miter_distance);
                    full_miter = Clipper.SimplifyPolygons(full_miter, PolyFillType.pftNonZero);
                    fulls.Add(full_miter);
                }
                else
                {
                    fulls.Add(full);
                }
            }

            for (int i = 0; i < clust_ids.Length; i++)
            {
                clust_ids[i] += polygon_lib.Count;
            }

            for (int i = 0; i < fulls.Count; i++)
            {
                polygon_lib.Add(new PolyRef()
                {
                    poly = fulls[i], trans = Mat3x3.Eye()
                });
            }

            return(clust_ids);
        }