<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Infinity Code Forum — Buffer Area]]></title>
		<link>https://forum.infinity-code.com/viewtopic.php?id=224</link>
		<atom:link href="https://forum.infinity-code.com/extern.php?action=feed&amp;tid=224&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[The most recent posts in Buffer Area.]]></description>
		<lastBuildDate>Mon, 01 Aug 2016 21:37:25 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Buffer Area]]></title>
			<link>https://forum.infinity-code.com/viewtopic.php?pid=1009#p1009</link>
			<description><![CDATA[<p>In this example, points are generated InitGeofences (first method).<br />I do not know your areas, so that it generates randomly.<br />You can specify your areas directly, load from a file or database.</p>]]></description>
			<author><![CDATA[null@example.com (Alex Vertax)]]></author>
			<pubDate>Mon, 01 Aug 2016 21:37:25 +0000</pubDate>
			<guid>https://forum.infinity-code.com/viewtopic.php?pid=1009#p1009</guid>
		</item>
		<item>
			<title><![CDATA[Re: Buffer Area]]></title>
			<link>https://forum.infinity-code.com/viewtopic.php?pid=1008#p1008</link>
			<description><![CDATA[<p>Thanks for this Alex, sorry for being a pain, but in which part of the scripts are the points defined?</p><p>I the meantime I came up with a more primitive solution, I created a 3 marker then created a 3d shape over the map and used colliders to check if the 3d marker is within the 3d shape (geofence).</p><p>Regards</p><p>Gus</p>]]></description>
			<author><![CDATA[null@example.com (gus)]]></author>
			<pubDate>Mon, 01 Aug 2016 20:57:08 +0000</pubDate>
			<guid>https://forum.infinity-code.com/viewtopic.php?pid=1008#p1008</guid>
		</item>
		<item>
			<title><![CDATA[Re: Buffer Area]]></title>
			<link>https://forum.infinity-code.com/viewtopic.php?pid=1007#p1007</link>
			<description><![CDATA[<p>Hello.</p><p>You can do this using textures.<br />For example, convert geographic coordinates to the texture coordinates, and find the closest pink point using some algorithm (eg, A-Star).<br />But I think it will be very slow solution, because it requires a lot of of calculations.</p><p>Much better is define the geofence as an array of points.<br />For example:<br /></p><div class="codebox"><pre><code>using System;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

public class GeofenceExample : MonoBehaviour
{
    public List&lt;Geofence&gt; geofences;

    private void InitGeofences()
    {
        int countGeofences = Random.Range(5, 10);
        geofences = new List&lt;Geofence&gt;();

        for (int i = 0; i &lt; countGeofences; i++)
        {
            int countPoints = Random.Range(4, 20);
            float radius = Random.Range(1, 10f);
            double centerLng = Random.Range(-180, 180f);
            double centerLat = Random.Range(-60, 60f);
            float radiusOffset = Random.Range(0, radius / 4);
            float angleOffset = Random.Range(0, 180f / countPoints);

            double[] points = new double[countPoints * 2];
            double left = double.PositiveInfinity, right = double.NegativeInfinity, top = double.NegativeInfinity, bottom = double.PositiveInfinity;

            List&lt;Vector2&gt; drawingPoints = new List&lt;Vector2&gt;();

            for (int j = 0; j &lt; countPoints; j++)
            {
                float angle = 360f / countPoints * j + Random.Range(-angleOffset, angleOffset);
                double lng = centerLng + Random.Range(radius - radiusOffset, radius + radiusOffset) * Mathf.Cos(angle * Mathf.Deg2Rad);
                double lat = centerLat + Random.Range(radius - radiusOffset, radius + radiusOffset) * Mathf.Sin(angle * Mathf.Deg2Rad);
                drawingPoints.Add(new Vector2((float) lng, (float) lat));
                if (left &gt; lng) left = lng;
                if (right &lt; lng) right = lng;
                if (top &lt; lat) top = lat;
                if (bottom &gt; lat) bottom = lat;
                points[j * 2] = lng;
                points[j * 2 + 1] = lat;
            }

            geofences.Add(new Geofence
            {
                id = i.ToString(),
                left = left,
                right = right,
                top = top,
                bottom = bottom,
                points = points
            });

            OnlineMaps.instance.AddDrawingElement(new OnlineMapsDrawingPoly(drawingPoints, Color.red, 3));
        }
    }

    private void OnMapClick()
    {
        double lng, lat;
        OnlineMapsControlBase.instance.GetCoords(out lng, out lat);

        double closestSqrDistance = double.PositiveInfinity;

        foreach (Geofence geofence in geofences)
        {
            if (geofence.Contains(lng, lat, ref closestSqrDistance))
            {
                Debug.Log(&quot;Hit &quot; + geofence.id);
                return;
            }
        }

        Debug.Log(&quot;Closest Distance &quot; + Math.Sqrt(closestSqrDistance) + &quot; km&quot;);
    }

    private void Start()
    {
        InitGeofences();
        OnlineMapsControlBase.instance.OnMapClick += OnMapClick;
    }

    public class Geofence
    {
        public string id;

        // The boundaries of geofence.
        public double left, right, top, bottom;

        // Points of geofence (0 - lng, 1 - lat, 2 - lng, 3 - lat, ...).
        // Or it can be Vector2[].
        public double[] points;

        public bool Contains(double lng, double lat, ref double closestSqrDistance)
        {
            double d = left - lng;
            if (d &gt; 180) lng += 360;
            else if (d &lt; -180) lng -= 360;

            if (lng &lt; left || lng &gt; right || lat &gt; top || lat &lt; bottom)
            {
                double dx, dy;
                OnlineMapsUtils.DistanceBetweenPoints(left, top, lng, lat, out dx, out dy);
                if (dx * dx + dy * dy &lt; closestSqrDistance)
                {
                    UpdateClosestDistance(lng, lat, ref closestSqrDistance);
                    return false;
                }

                OnlineMapsUtils.DistanceBetweenPoints(right, top, lng, lat, out dx, out dy);
                if (dx * dx + dy * dy &lt; closestSqrDistance)
                {
                    UpdateClosestDistance(lng, lat, ref closestSqrDistance);
                    return false;
                }

                OnlineMapsUtils.DistanceBetweenPoints(left, bottom, lng, lat, out dx, out dy);
                if (dx * dx + dy * dy &lt; closestSqrDistance)
                {
                    UpdateClosestDistance(lng, lat, ref closestSqrDistance);
                    return false;
                }

                OnlineMapsUtils.DistanceBetweenPoints(right, bottom, lng, lat, out dx, out dy);
                if (dx * dx + dy * dy &lt; closestSqrDistance) UpdateClosestDistance(lng, lat, ref closestSqrDistance);

                return false;
            }

            bool isPointInPolygon = OnlineMapsUtils.IsPointInPolygon(points, lng, lat);
            if (!isPointInPolygon) UpdateClosestDistance(lng, lat, ref closestSqrDistance);
            else closestSqrDistance = 0;

            return isPointInPolygon;
        }

        private void UpdateClosestDistance(double lng, double lat, ref double closestSqrDistance)
        {
            for (int i = 0; i &lt; points.Length; i += 2)
            {
                double dx, dy;
                OnlineMapsUtils.DistanceBetweenPoints(lng, lat, points[i], points[i + 1], out dx, out dy);
                double sqrDistance = dx * dx + dy * dy;
                if (sqrDistance &lt; closestSqrDistance) closestSqrDistance = sqrDistance;
            }
        }
    }
}</code></pre></div><p>This will work much faster.</p><p>It uses a small cheating - is calculated the distance to the point.<br />If you want a more accurate result, use OnlineMapsUtils.NearestPointStrict.</p>]]></description>
			<author><![CDATA[null@example.com (Alex Vertax)]]></author>
			<pubDate>Mon, 01 Aug 2016 20:06:47 +0000</pubDate>
			<guid>https://forum.infinity-code.com/viewtopic.php?pid=1007#p1007</guid>
		</item>
		<item>
			<title><![CDATA[Buffer Area]]></title>
			<link>https://forum.infinity-code.com/viewtopic.php?pid=1006#p1006</link>
			<description><![CDATA[<p>Hi </p><p>I want to create a sort of geofence that would start an action if the user crosses beyond it.<br />Attached you can see the map I am working with, I would like to detect the distance between the user and the pink boundary line around Gibraltar and then run actions depending on the distance.<br />Is it possible to do this? what would be the best way, using an overlay, or colour detection.<br />I am using offline- resources, tiles and keeping zoom to a single level for now.</p><p>An idea I was thinking, if we duplicate the OnlineMapsTiles folder and then create new duplicate map textures then delete unused areas and just leave black area to use as geofence texture like using an alpha channel, could you work some of your magic so that these could be used to add geofences. So you could detect if you are in a black area and how far away from the edge of&nbsp; the black area the user is.</p><p>Is something along these lines feasible or is there a better solution?</p><p>Looking forward to your assistance.<br />Best regards<br />G.</p>]]></description>
			<author><![CDATA[null@example.com (gus)]]></author>
			<pubDate>Mon, 01 Aug 2016 16:10:39 +0000</pubDate>
			<guid>https://forum.infinity-code.com/viewtopic.php?pid=1006#p1006</guid>
		</item>
	</channel>
</rss>
