Skip to content

Commit

Permalink
Moved GetBisector and OffsetPolygon from RoofGenerator to Geometry
Browse files Browse the repository at this point in the history
  • Loading branch information
BasmanovDaniil committed Jul 18, 2018
1 parent 7ec0139 commit ff54823
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 42 deletions.
46 changes: 4 additions & 42 deletions Examples/Buildings/RoofGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;

namespace ProceduralToolkit.Examples
{
Expand All @@ -15,7 +14,7 @@ public static MeshDraft Generate(
float roofHeight,
RoofConfig roofConfig)
{
List<Vector2> roofPolygon = OffsetPolygon(foundationPolygon, roofConfig.overhang);
List<Vector2> roofPolygon = Geometry.OffsetPolygon(foundationPolygon, roofConfig.overhang);

MeshDraft roofDraft;
switch (roofConfig.type)
Expand Down Expand Up @@ -90,6 +89,7 @@ public static MeshDraft GenerateHipped(List<Vector2> roofPolygon, RoofConfig roo
Vector3 ridgeOffset = (b - a).normalized*2;
Vector3 ridge0 = (a + d)/2 + ridgeHeight + ridgeOffset;
Vector3 ridge1 = (b + c)/2 + ridgeHeight - ridgeOffset;

var roofDraft = new MeshDraft();
roofDraft.AddQuad(a, ridge0, ridge1, b);
roofDraft.AddTriangle(b, ridge1, c);
Expand All @@ -102,52 +102,14 @@ private static MeshDraft GenerateBorder(List<Vector2> roofPolygon, RoofConfig ro
{
List<Vector3> lowerRing = roofPolygon.ConvertAll(v => v.ToVector3XZ());
List<Vector3> upperRing = roofPolygon.ConvertAll(v => v.ToVector3XZ() + Vector3.up*roofConfig.thickness);
var border = new MeshDraft().AddFlatQuadBand(lowerRing, upperRing, false);
return border;
return new MeshDraft().AddFlatQuadBand(lowerRing, upperRing, false);
}

private static MeshDraft GenerateOverhang(List<Vector2> foundationPolygon, List<Vector2> roofPolygon)
{
List<Vector3> lowerRing = foundationPolygon.ConvertAll(v => v.ToVector3XZ());
List<Vector3> upperRing = roofPolygon.ConvertAll(v => v.ToVector3XZ());
var overhang = new MeshDraft().AddFlatQuadBand(lowerRing, upperRing, false);
return overhang;
}

private static List<Vector2> OffsetPolygon(List<Vector2> polygon, float distance)
{
var newPolygon = new List<Vector2>();
for (int i = 0; i < polygon.Count; i++)
{
var previous = polygon.GetLooped(i - 1);
var current = polygon[i];
var next = polygon.GetLooped(i + 1);
float angle;
Vector2 bisector = GetBisector(previous, current, next, out angle);
float hypotenuse = distance/GetBisectorSin(angle);

newPolygon.Add(current + bisector*hypotenuse);
}
return newPolygon;
}

private static Vector2 GetBisector(Vector2 previous, Vector2 current, Vector2 next, out float angle)
{
Vector2 toPrevious = (previous - current).normalized;
Vector2 toNext = (next - current).normalized;

angle = VectorE.SignedAngle(toPrevious, toNext);
Assert.IsFalse(float.IsNaN(angle));
return toPrevious.RotateCW(angle/2);
}

private static float GetBisectorSin(float angle)
{
if (angle > 180)
{
angle = 360 - angle;
}
return Mathf.Sin(angle/2*Mathf.Deg2Rad);
return new MeshDraft().AddFlatQuadBand(lowerRing, upperRing, false);
}
}

Expand Down
50 changes: 50 additions & 0 deletions Scripts/Geometry/Geometry.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.Assertions;

namespace ProceduralToolkit
{
Expand All @@ -10,6 +11,8 @@ public static class Geometry
{
public const float Epsilon = 0.00001f;

#region Point samplers

/// <summary>
/// Returns a point on a circle in the XY plane
/// </summary>
Expand Down Expand Up @@ -175,5 +178,52 @@ public static Vector3 PointOnTeardrop(float radius, float height, float horizont
y: height*sinVertical,
z: radius*Mathf.Cos(horizontalRadians)*teardrop);
}

#endregion Point samplers

/// <summary>
/// Returns the bisector of an angle
/// </summary>
/// <param name="previous">Previous vertex</param>
/// <param name="current">Current vertex</param>
/// <param name="next">Next vertex</param>
/// <param name="degrees">Value of an angle in degrees</param>
public static Vector2 GetAngleBisector(Vector2 previous, Vector2 current, Vector2 next, out float degrees)
{
Vector2 toPrevious = (previous - current).normalized;
Vector2 toNext = (next - current).normalized;

degrees = VectorE.SignedAngle(toPrevious, toNext);
Assert.IsFalse(float.IsNaN(degrees));
return toPrevious.RotateCW(degrees/2);
}

/// <summary>
/// Offsets the supplied polygon. Does not handle intersections.
/// </summary>
/// <param name="polygon">Vertices of the polygon</param>
/// <param name="distance">Offset distance. Positive values offset inside, negative outside.</param>
public static List<Vector2> OffsetPolygon(List<Vector2> polygon, float distance)
{
var newPolygon = new List<Vector2>();
for (int i = 0; i < polygon.Count; i++)
{
Vector2 previous = polygon.GetLooped(i - 1);
Vector2 current = polygon[i];
Vector2 next = polygon.GetLooped(i + 1);

float angle;
Vector2 bisector = GetAngleBisector(previous, current, next, out angle);

if (angle > 180)
{
angle = 360 - angle;
}
float hypotenuse = distance/Mathf.Sin(angle/2*Mathf.Deg2Rad);

newPolygon.Add(current + bisector*hypotenuse);
}
return newPolygon;
}
}
}

0 comments on commit ff54823

Please sign in to comment.