예제 #1
0
 /// <summary>Finds the lowest distance of point P to a line segment defined by points A and B</summary>        
 public static float distance_from_point_to_segment(crds2 a, crds2 b, crds2 p)
 {
     float l2 = a.dist_squared(b);
     if (l2 < 0.000001f) return a.dist(p); // case : a == b
     float t = crds2.dot(p-a, b-a) / l2;
     if (t < 0f) return a.dist(p);
     if (t > 1f) return b.dist(p);
     crds2 proj =  a.lerp(b, t);
     return proj.dist(p);
 }
예제 #2
0
        public static bool are_points_clockwise(crds2[] polygon)
        {
            var sum = 0f;

            for (int i = 0; i < polygon.Length-1; i++)
            {
                sum += (polygon[i+1].x - polygon[i ].x) * (polygon[i + 1].y + polygon[i].y);
            }

            return sum > 0;
        }
예제 #3
0
        public void render(crds2 screen_coords, float alpha_multiplier = 1f, float scale_multiplier = 1f, float temperature = 0f)
        {
            foreach (var layer in _layers)
            {
                var spr = Graphics.add_sprite(layer.texture, screen_coords.x, screen_coords.y);

                spr.set_scale(layer.scale * scale_multiplier);
                spr.set_colors(layer.color, layer.alpha * alpha_multiplier);
                spr.blit.sequence.x = (uint)layer.sequence_x;
                spr.blit.sequence.y = (uint)layer.sequence_y;
            }
        }
예제 #4
0
        /// <summary>same as segment-segment int. but points only define the line, don't limit it</summary>        
        public static bool line_line_intersection(crds2 A, crds2 B, crds2 C, crds2 D, out crds2 intersection_point)
        {
            intersection_point = crds2.zero;

            var z = (D.y - C.y) * (B.x - A.x) - (D.x - C.x) * (B.y - A.y);
            if (z.approximately(0f)) return false;

            var U1 = ((D.x - C.x) * (A.y - C.y) - (D.y - C.y) * (A.x - C.x)) / z;
            var U2 = ((B.x - A.x) * (A.y - C.y) - (B.y - A.y) * (A.x - C.x)) / z;

            intersection_point = A.lerp(B, U1);
            return true;
        }
예제 #5
0
 public static crds2 centroid_of_polygon(crds2[] polygon)
 {
     var n = polygon.Length;
     float sum = 0f;
     for (int i = 0; i < n; i++)
     {
         var j = i + 1; if (j == n) j = 0;
         sum += polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y;
     }
     var surf = sum / 2;
     crds2 coordz = crds2.zero;
     for (int i = 0; i < n; i++) { var j = i + 1; if (j == n) j = 0;
         coordz.x += (polygon[i].x + polygon[j].x) * (polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y);
         coordz.y += (polygon[i].y + polygon[j].y) * (polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y);
     }
     coordz.x /= 6 * surf;
     coordz.y /= 6 * surf;
     return coordz;
 }
예제 #6
0
        public static void encompass(crds2 hi_extr, crds2 lo_extr, float zoom_factor = 1f)
        {
            var c = (hi_extr + lo_extr) * 0.5f;
            var dhor = XMath.abs((hi_extr - lo_extr).x);
            var dver = XMath.abs((hi_extr - lo_extr).y);
            if (dhor < 1f) dhor = 1f;
            if (dver < 1f) dver = 1f;

            var aspect = dhor / dver;
            var screen_aspect = (float)Graphics.screen_w / Graphics.screen_h;

            var desired_zoom = 1f;

            if (aspect > screen_aspect) // width rules
                desired_zoom = (float)Graphics.screen_w / dhor;
            else // height rules
                desired_zoom = (float)Graphics.screen_h / dver;

            _target = new crds4(c.x, c.y, 0f, desired_zoom * zoom_factor);
            current = _target;
            delta = default(crds4);
            raise_restrictions();
        }
예제 #7
0
 /// <summary>Returns the point of projection of point P on a segment defined by A and B, expressed as a float interpolation value between A and B</returns>
 public static float projection_of_point_on_segment(crds2 a, crds2 b, crds2 p)
 {
     return crds2.dot(p - a, b - a) / a.dist_squared(b);
 }
예제 #8
0
 // this also works perfectly if you change crds2 into crds3
 public static crds2 bezier_at(crds2 A, crds2 M, crds2 B, float t)
 {
     var q = 1f - t;
     return ((A * q + M * t) * q + (M * q + B * t) * t);
 }
예제 #9
0
            public bool contains(crds2 point, float tolerance = 0f)
            {
                if ( point.x > lo.x - tolerance
                  && point.x < hi.x + tolerance
                  && point.y > lo.y - tolerance
                  && point.y < hi.y + tolerance) return true;

                return false;
            }
예제 #10
0
 public rect(float x0, float y0, float w, float h)
 {
     lo = new crds2(x0, y0);
     hi = new crds2(x0 + w, y0 + h);
 }
예제 #11
0
        /// <summary>Returns a boolean stating whether there is ANY overlap between two triangles</summary>
        /// <param name="first_triangle">an array of exactly THREE 2d vertices defining the FIRST triangle</param>
        /// <param name="second_triangle">an array of exactly THREE 2d vertices defining the SECOND triangle</param>        
        public static bool triangle_triangle_intersection(crds2[] first_triangle, crds2[] second_triangle)
        {
            if (first_triangle.Length != 3 || second_triangle.Length != 3) throw new Exception("triangle triangle intersection error - not a triangle!");

            // if any vertex of triangle A is in triangle B, or any vertex of triangle B is in triangle A, return true
            for (int i = 0; i < 3; i++) if (point_in_triangle(first_triangle[0], first_triangle[1], first_triangle[2], second_triangle[i])) return true;
            for (int i = 0; i < 3; i++) if (point_in_triangle(second_triangle[0], second_triangle[1], second_triangle[2], first_triangle[i])) return true;

            // no luck yet huh? ok, if any two segments intersect overlap

            crds2 p;

            for (int a = 0; a < 3; a++)
            for (int b = 0; b < 3; b++)
            {
                var a2 = a + 1; if (a2 == 3) a2 = 0;
                var b2 = b + 1; if (b2 == 3) b2 = 0;
                if (segment_segment_intersection(first_triangle[a], first_triangle[a2], second_triangle[b], second_triangle[b2], out p)) return true;
            }

            // nope? Huh. Guess there is no intersection. Huh.
            return false;
        }
예제 #12
0
        public static void set_extremes(crds2 upper_left, crds2 lower_right, float min_zoom, float max_zoom)
        {
            restrictions_low.x = upper_left.x;
            restrictions_low.y = upper_left.y;

            restrictions_high.x = lower_right.x;
            restrictions_high.y = lower_right.y;

            restrictions_low.w = min_zoom * ZOOM_FACTOR;
            restrictions_high.w = max_zoom * ZOOM_FACTOR;

            set_target(upper_left.lerp(lower_right, 0.5f));
        }
예제 #13
0
 public static void set_target(crds2 coords)
 {
     _target.x = coords.x;
     _target.y = coords.y;
 }
예제 #14
0
 public static crds3 unproject(crds2 screen_coords)
 {
     var x = (screen_coords.x - Graphics.scrW2) / zoom + current.x;
     var y = (screen_coords.y - Graphics.scrH2) / (zoom * cos_phi) + current.y;
     //var A = (Graphics.scrH2 - screen_coords.y) / zoom;
     //var B = current.z * inv_cos_phi;
     //var y = (A + B) * inv_cos_phi + current.y;
     return new crds3(x, y, 0);
 }
예제 #15
0
 public static Sprite add_shape(crds2[] coords, uint color = 0xffffffffu)
 {
     Sprite spr = current_layer.new_sprite;
     spr.coords.set(0f, 0f);
     spr.kind = Sprite.draw_mode.poly;
     spr.blit.color = color;
     spr.points = coords;
     last_sprite = spr;
     return spr;
 }
예제 #16
0
        static public Sprite[] add_capsule(Texture t, float x0, float y0, float x1, float y1, float w) // capsule extends the line outwards from the points
        {
            var center = current_layer.new_sprite;
            var left = current_layer.new_sprite;
            var right = current_layer.new_sprite;

            var array = new Sprite[] { left, center, right };

            var c = new crds2((x0 + x1) / 2, (y0 + y1) / 2);
            var d = (float)Math.Sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1)); if (d <= 0.5f) d = 0.5f;
            var h = w / t.size.y;
            var aspect = (float)t.size.x / t.size.y;
            var invaspect = 1f / aspect;
            var v = invaspect / 2;
            var rot_angle = XMath.get_angle(x1 - x0, y1 - y0);
            var d1 = crds2.deflect(c, new crds2(x0, y0), w / 4f);
            var d2 = crds2.deflect(c, new crds2(x1, y1), w / 4f);

            var scalex = d / t.size.x;

            center.coords.set(c.x, c.y);
            center.set_scale(scalex, h);
            center.blit.set_special_margins(v, 0f, 1f - v * 2, 1f, true);

            left.coords.set(d1.x, d1.y);            
            left.blit.set_special_margins(0f, 0f, v, 1f, true);
            left.set_scale(h, h);

            right.coords.set(d2.x, d2.y);
            right.blit.set_special_margins(1f - v, 0f, v, 1f, true);
            right.set_scale(h, h);
            
            foreach (var spr in array) {                
                spr.blit.t = t;
                spr.blit.rotation = rot_angle;
                spr.kind = Sprite.draw_mode.spr;
            }
            //left.set_colors(0xff0000, 0.5f);
            //center.set_colors(0x00ff00, 0.5f);
            //right.set_colors(0x0000ff, 0.5f);
            last_sprite = right;
            return array;
            
        }
예제 #17
0
        private static void render_text_advanced(Sprite spr)
        {
            Texture t = spr.txt.font_id.tex;
            BitmapFont f = spr.txt.font_id;
            #region SFML sprite state set

            sfml_spr.Image = t.image;
            sfml_spr.BlendMode = (SFML.Graphics.BlendMode)spr.blit.mode;
            sfml_spr.Color = familiarize_color(spr.blit.color);
            sfml_spr.Rotation = 0.0f;
            sfml_spr.Origin = new Vector2f(0f, 0f);// new Vector2f(spr.blit.scale.x, spr.blit.scale.y);
            sfml_spr.Scale = new Vector2f(spr.blit.scale.x, spr.blit.scale.y);

            #endregion

            float x_offset = 0.0f, y_offset = 0.0f;
            for (int c = 1, n = spr.txt.txt.Length; c < n; c++)
            {
                char a = spr.txt.txt[c];
                if (a == '|') // new line
                {
                    y_offset += (f.v_spacing) * spr.blit.scale.y;
                    x_offset = 0;
                }
                else if (a == '#') // DIRECTIVE
                {
                    char d = spr.txt.txt[c + 1];
                    if (d == 'C') // directive is COLOR
                    {
                        uint color = 0;
                        var param = find_directive_param(spr.txt.txt, c, out c);

                        if      (param == "0") color = spr.blit.color;
                        else if (param == "R") color = 0xff0000;
                        else if (param == "G") color = 0x00ff00;
                        else if (param == "B") color = 0x0000ff;
                        else if (param == "Y") color = 0xffff00;
                        else if (param == "P") color = 0xff00ff;
                        else if (param == "O") color = 0xff8000;

                        sfml_spr.Color = familiarize_color(0xff000000 | color);
                    }
                    else if (d == 'K') // Krest
                    {
                        var param = find_directive_param(spr.txt.txt, c, out c);
                        Crest crest =  Crest.find(param);
                        var crest_correction = new crds2(8f, 3f);
                        if (crest != null) crest.render(crest_correction + new crds2(spr.coords.x + x_offset, spr.coords.y + y_offset), (1f / 255f) * sfml_spr.Color.A);
                        x_offset += 24f;
                    }
                }
                else // letter!
                {
                    uint sx = f.char_data[a].seq_x; uint sy = f.char_data[a].seq_y;

                    sfml_spr.Origin     = new Vector2f(0f, 0f);
                    sfml_spr.Position   = new Vector2f(spr.coords.x + x_offset, spr.coords.y + y_offset);
                    sfml_spr.SubRect    = new SFML.Graphics.IntRect(    (int)(t.size.x * sx),
                                                                        (int)(t.size.y * sy),
                                                                        (int)(t.size.x),// * (sx + 1)),
                                                                        (int)(t.size.y));// * (sy + 1)));
                    render_target.Draw(sfml_spr, spr.effect.shader.sfml_shader_object);

                    x_offset += (f.char_data[a].width + f.h_spacing) * spr.blit.scale.x;
                }
            }
        }
예제 #18
0
 public static void move_center(crds2 coords)
 {
     _target.x += coords.x;
     _target.y += coords.y;
 }
예제 #19
0
 /// <summary>returns whether a point p lies to the LEFT side of a line defined by points line_a and line_b</summary>        
 /// <returns>true if the point is "left" of the line as defined by direction from line_a to line_b</returns>
 public static bool is_left(crds2 line_a, crds2 line_b, crds2 p)
 {
     return ((line_b.x - line_a.x) * (p.y - line_a.y) - (line_b.y - line_a.y) * (p.x - line_a.x)) > 0;
 }
예제 #20
0
 public static crds2 random_point_in_triangle(crds2 A, crds2 B, crds2 C)
 {
     var a = Random.range(0f, 1f);
     var b = Random.range(0f, 1f);
     if (a + b > 1f) { a = 1f - a; b = 1f - b; }
     var c = 1f - a - b;
     return A * a + B * b + C * c;
 }
예제 #21
0
        //static public bool random_point_in_polygon(crds2[] poly)
        //{
        //}
        /// <summary>concept nabbed from http://www.blackpawn.com/texts/pointinpoly/default.html </summary>        
        /// <returns>true if point p is in triangle (A, B, C)</returns>
        public static bool point_in_triangle(crds2 A, crds2 B, crds2 C, crds2 p)
        {
            // Compute vectors
            var v0 = C - A;
            var v1 = B - A;
            var v2 = p - A;

            // Compute dot products
            var dot00 = crds2.dot(v0, v0);
            var dot01 = crds2.dot(v0, v1);
            var dot02 = crds2.dot(v0, v2);
            var dot11 = crds2.dot(v1, v1);
            var dot12 = crds2.dot(v1, v2);

            // Compute barycentric coordinates
            var invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
            var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
            var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
            // Check if point is in triangle
            return (u > 0f) && (v > 0f) && (u + v < 1f);
        }
예제 #22
0
        /// <summary> Returns the point of intersection of two segments, where first segment is defined by A and B, and 2nd segment by C and D. </summary>        
        /// <param name="A">Point A</param><param name="B">Point B</param><param name="C">Point C</param><param name="D">Point D</param><param name="intersection_point">Intersection point, if any</param>
        /// <returns>True if there is an intersection, and if so, fills intersection_point with the exact location</returns>
        public static bool segment_segment_intersection(crds2 A, crds2 B, crds2 C, crds2 D, out crds2 intersection_point)
        {
            intersection_point = crds2.zero;

            var z = (D.y - C.y) * (B.x - A.x) - (D.x - C.x) * (B.y - A.y);
            if (z.approximately(0f)) return false;

            var U1 = ((D.x - C.x) * (A.y - C.y) - (D.y - C.y) * (A.x - C.x)) / z;
            var U2 = ((B.x - A.x) * (A.y - C.y) - (B.y - A.y) * (A.x - C.x)) / z;
            if ((U1 >= 0f && U1 <= 1f) && (U2 >= 0f && U2 <= 1f))
            {
                intersection_point = A.lerp(B, U1);
                return true;
            }
            return false;
        }
예제 #23
0
 public static float surface_of_polygon(crds2[] polygon)
 {
     var n = polygon.Length;
     float sum = 0f;
     for (int i = 0; i < n; i++)
     {
         var j = i + 1; if (j == n) j = 0;
         sum += polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y;
     }
     return XMath.abs(sum * 0.5f); // SUM is now the full SURFACE of the polygon
 }
예제 #24
0
 public static crds3 project(crds2 world_coords)
 {
     var c = world_coords;
     var me = current + delta * Session.interpolation;
     return new crds3(
         Graphics.scrW2 + (c.x - me.x) * zoom,
         Graphics.scrH2 + ((c.y - me.y) * cos_phi) * zoom,
         zoom);
 }