<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex M.</title>
    <description>The latest articles on DEV Community by Alex M. (@bogdanalexandru).</description>
    <link>https://dev.to/bogdanalexandru</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F312053%2F7763c3e7-7c3f-4a11-bfce-303edd2703a9.jpg</url>
      <title>DEV Community: Alex M.</title>
      <link>https://dev.to/bogdanalexandru</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bogdanalexandru"/>
    <language>en</language>
    <item>
      <title>Generating Random Points within a Polygon in Unity</title>
      <dc:creator>Alex M.</dc:creator>
      <pubDate>Thu, 09 Jan 2020 18:26:49 +0000</pubDate>
      <link>https://dev.to/bogdanalexandru/generating-random-points-within-a-polygon-in-unity-nce</link>
      <guid>https://dev.to/bogdanalexandru/generating-random-points-within-a-polygon-in-unity-nce</guid>
      <description>&lt;p&gt;Scenario: you want to define a polygonal area in your scene and pick random locations on it, for example to have a NPC roam within. There's no one-shot solution for this that I'm aware of, but there's at least one method for picking uniform random points within a triangle. Since polygons can be triangulated, we can apply the triangle formula in the context of the polygon.&lt;/p&gt;

&lt;p&gt;The code is &lt;a href="https://github.com/BogdanAlexandru/UnityTriangleNetExample"&gt;here&lt;/a&gt;, but since it's really just about three non-glue scripts with very few functions, I recommend writing your own as you learn the ideas from the article.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;Given a triangle with vertices &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt;, you can find a random point &lt;code&gt;P&lt;/code&gt; within the triangle with the formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HNpc9BZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/eo1u4kwyf125iqgvcjrp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HNpc9BZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/eo1u4kwyf125iqgvcjrp.png" alt="P = (1 - sqrt(r_1)) * A + (sqrt(r_1) * (1 - r_2)) * B + (r_2 sqrt(r_1))* C" width="520" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;where &lt;code&gt;r1&lt;/code&gt; and &lt;code&gt;r2&lt;/code&gt; are uniformly distributed random numbers in &lt;code&gt;[0, 1]&lt;/code&gt; i.e. as returned by &lt;code&gt;UnityEngine.Random.Range(0f, 1f)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1eFtKJoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zmzi60sz6ruy9xglnwpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1eFtKJoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zmzi60sz6ruy9xglnwpb.png" alt="Sample illustration of 1000 points in interval 0, 1" width="578" height="454"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;center&gt;&lt;em&gt;1000 points within &lt;code&gt;[(0, 0), (0, 1), (1, 0)]&lt;/code&gt;&lt;/em&gt;&lt;/center&gt;

&lt;p&gt;We can apply the formula in the context of any polygonal shape if said shape is triangulated. For the triangulation process you can use an existing library that already implements &lt;a href="https://en.wikipedia.org/wiki/Delaunay_triangulation"&gt;Delaunay triangulations&lt;/a&gt;, such as &lt;a href="https://archive.codeplex.com/?p=triangle"&gt;Triangle.net&lt;/a&gt;, or write your own (it's not trivial, in case you're not sure you've got the time to spend). &lt;/p&gt;

&lt;p&gt;I gave Triangle.net a shot and it appeared to work just fine for what I threw at it. The official distribution should work fine now that Unity supports .NET 4.6 but to avoid any kind of hassle I used &lt;a href="https://github.com/BogdanAlexandru/Triangle.NET"&gt;this fork&lt;/a&gt; which was already confirmed to work with Unity.&lt;/p&gt;

&lt;p&gt;Before we start throwing triangles around though, we need a polygon.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up the Polygon
&lt;/h2&gt;

&lt;p&gt;An &lt;code&gt;Area&lt;/code&gt; script can be defined, which will have a &lt;code&gt;List&amp;lt;Vector3&amp;gt;&lt;/code&gt; of vertices that describe the polygonal shape.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Area&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MonoBehaviour&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Corners&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;//                   or vertices&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want to be able to edit this polygon in the scene view, so a custom editor for the &lt;code&gt;Area&lt;/code&gt; component needs to be written.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://catlikecoding.com/unity/tutorials/curves-and-splines/"&gt;This tutorial&lt;/a&gt; that deals with Bezier curves, or at least the first quarter of it, teaches all that you need to get this done, so if you're not sure how to proceed, give it a shot. In short, we're not doing much more than drawing lines between points and using handles to move said points around.&lt;/p&gt;

&lt;p&gt;This is the end result for me (note that here the polygon is already being triangulated):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CfClf3WH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zaxrwvzn9w2lloxyp3mu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CfClf3WH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zaxrwvzn9w2lloxyp3mu.gif" alt="Animation" width="509" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end, you want the &lt;code&gt;Area&lt;/code&gt; script to expose a &lt;code&gt;PickRandomLocation&lt;/code&gt; function or similar, allowing calls like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RoamingAI&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MonoBehaviour&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Map this to the area you need in the inspector&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Area&lt;/span&gt; &lt;span class="n"&gt;RoamingArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// later on...&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RoamingArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PickRandomLocation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Triangulating the Polygon
&lt;/h2&gt;

&lt;p&gt;With a set of vertices that describe the polygon, we can ask Triangle.Net to do some triangulation for us.&lt;/p&gt;

&lt;p&gt;This is my function that calls into Triangle.Net:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ICollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Triangle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Triangulate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Vector2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;poly&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Polygon&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;poly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Contour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToVertex&lt;/span&gt;&lt;span class="p"&gt;())));&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mesh&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;poly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Triangulate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Triangles&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Vector2&lt;/code&gt;s given as input are the &lt;code&gt;Vector3&lt;/code&gt; vertices of the &lt;code&gt;Area&lt;/code&gt;, with the &lt;code&gt;z&lt;/code&gt; coordinate taking the place of &lt;code&gt;y&lt;/code&gt;. In other words, &lt;code&gt;area.Vertices.Select(v =&amp;gt; new Vector2(v.x, v.z))&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Polygon&lt;/code&gt; is a Triangle.Net type, as are &lt;code&gt;Contour&lt;/code&gt; and &lt;code&gt;Vertex&lt;/code&gt;. We turn a &lt;code&gt;Vector2&lt;/code&gt; into a &lt;code&gt;Vertex&lt;/code&gt; via an extension method called &lt;code&gt;ToVertex&lt;/code&gt; that does nothing more than &lt;code&gt;new Vertex(vec2.x, vec2.y)&lt;/code&gt;. Then, we build a &lt;code&gt;Contour&lt;/code&gt; out of our vertices and add it to the &lt;code&gt;Polygon&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;Polygon&lt;/code&gt; set up, all that's left is to call &lt;code&gt;Triangulate()&lt;/code&gt; on it, which gives us back an &lt;code&gt;IMesh&lt;/code&gt; object, from which we only need the collection of &lt;code&gt;Triangle&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking a Random Triangle
&lt;/h2&gt;

&lt;p&gt;With the collection of triangles calculated, we can pick one to apply the random point formula on. We want the random positions to be picked as uniformly as possible, so simply choosing one of the triangles at random won't do:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Zt_TKlc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/s6uuu3gv66i1j9dl44vo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Zt_TKlc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/s6uuu3gv66i1j9dl44vo.png" alt="Not ideal distribution" width="640" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead we'll introduce some bias, so larger (by area) triangles become proportionately more likely to be selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The sum of the areas of the triangles can be cached.&lt;/span&gt;
&lt;span class="n"&gt;_areaSum&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;_triangles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_areaSum&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TriArea&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Triangle&lt;/span&gt; &lt;span class="nf"&gt;PickRandomTriangle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_areaSum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_triangles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// TriArea() is an extension method&lt;/span&gt;
        &lt;span class="c1"&gt;// that uses the cross product formula&lt;/span&gt;
        &lt;span class="c1"&gt;// to calculate the triangle's area.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_triangles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;TriArea&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_triangles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;_triangles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;TriArea&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Should normally not get here&lt;/span&gt;
    &lt;span class="c1"&gt;// so this is not 100% correct.&lt;/span&gt;
    &lt;span class="c1"&gt;// You'd need to consider floating&lt;/span&gt;
    &lt;span class="c1"&gt;// point arithmetic imprecision.&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// But this is a good compromise &lt;/span&gt;
    &lt;span class="c1"&gt;// that nonetheless gives good &lt;/span&gt;
    &lt;span class="c1"&gt;// results.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_triangles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Last&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s2JhzCPD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ws78uphl27jklmk2ijv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s2JhzCPD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ws78uphl27jklmk2ijv1.png" alt="Better distribution" width="635" height="470"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Much better.&lt;/em&gt;&lt;/center&gt;
&lt;h2&gt;
  
  
  Picking a Random Location
&lt;/h2&gt;

&lt;p&gt;With a &lt;code&gt;Triangle&lt;/code&gt; having been chosen, all that's left is to apply the aforementioned formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Vector2&lt;/span&gt; &lt;span class="nf"&gt;RandomWithinTriangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Triangle&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Mathf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1f&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;m3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetVertex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToVector2&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetVertex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToVector2&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetVertex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToVector2&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m3&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is our random position within the polygon describing the &lt;code&gt;Area&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Q&amp;amp;A
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I use this in a 3D world?
&lt;/h3&gt;

&lt;p&gt;Once you have the random 2D coordinates generated, &lt;code&gt;(x, z)&lt;/code&gt;, you can perform a raycast from &lt;code&gt;(x, HighEnoughY, z)&lt;/code&gt; downwards. Once you hit the terrain, get your final position by taking &lt;code&gt;hitPoint.y&lt;/code&gt; as your random point's &lt;code&gt;y&lt;/code&gt; coordinate.&lt;/p&gt;

&lt;p&gt;Remember to set your terrain on its own layer if it's not on one already, and make your raycast only hit the terrain layer via the layer mask argument. This will improve performance and reduce the chance that your character receives the top of a giant orc's head as destination.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I add holes within the polygon?
&lt;/h3&gt;

&lt;p&gt;Aside from the area vertices, you will need another set of vertices for each hole. Once you have that, instead of adding just the area vertices to the &lt;code&gt;Polygon&lt;/code&gt; that's to be triangulated, also add a &lt;code&gt;Contour&lt;/code&gt; for each hole:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Polygon&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Contour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verticesOfArea&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;holes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Contour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vertices&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mesh&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Triangulate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X9XQGvlb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uz3smnatorrhzr9mo7v1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X9XQGvlb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uz3smnatorrhzr9mo7v1.png" alt="sample screenshot" width="298" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the editor part, you may want to separate the &lt;code&gt;Area&lt;/code&gt; component into an &lt;code&gt;AreaPolygon&lt;/code&gt; and &lt;code&gt;Area&lt;/code&gt; pair, with the former only keeping track of the vertices that make up the polygon, and the latter taking in those vertices, triangulating the polygon and returning a random position. Add empty GameObjects as children to the &lt;code&gt;Area&lt;/code&gt; GameObjects, and give them &lt;code&gt;AreaPolygon&lt;/code&gt; components. The &lt;code&gt;Area&lt;/code&gt; component will gather all the Hole &lt;code&gt;AreaPolygon&lt;/code&gt; data from its children and consider each one as a hole inside its own polygon.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>math</category>
    </item>
  </channel>
</rss>
