Объявление
public static void Simplify(Listpublic static void Simplify(List
public static void Simplify(List
public static void Simplify(List
Параметры
points | Точки, из которых состоит исходная линия. |
tolerance | Это значение используется для оценки того, какие точки следует удалить из линии. Более высокое значение приводит к более простой линии (меньше точек). Положительное значение, близкое к нулю, приводит к тому, что линия практически не сокращается. Значение нуля или меньше не влияет. |
pointsToKeep | Заполняется этой функцией. Содержит индексы точек, которые должны быть сгенерированы в упрощенной версии. |
simplifiedPoints | Заполняется этой функцией. Содержит точки, образующие упрощенную линию. |
Описание
Создает упрощенную версию исходной линии, удаляя точки, находящиеся в пределах указанного допуска.
Например, вы можете использовать эту функцию для сокращения сложной линии, состоящей из тысяч точек. Линия может быть уменьшена до сотен или даже меньше точек и при этом сохранять форму, близко соответствующую оригиналу. Вы можете создать несколько версий одной и той же линии с различными уровнями детализации, настроив допуск (более высокие значения допуска приводят к меньшему количеству точек в сгенерированной линии). Затем сгенерированную линию можно отобразить с помощью системы LODGroup.
Алгоритм Simplify основан на алгоритме Ramer Douglas Peucker ; он создает линию, которая точно представляет предоставленную линию, но с меньшим количеством точек (определяется допуском).
Примечание. Эта функция может обрабатывать большое количество точек, поскольку она не является рекурсивной. Двухмерная версия этой функции работает лучше, чем эта функция, поскольку использует более простой способ оценки точек.
Посмотрите так же: LineRenderer.Simplify.
В следующем примере показано, как применить упрощение линии к существующей линии.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
// This example shows how to apply line simplification to a line that already contains points.
[RequireComponent(typeof(LineRenderer))]
public class SimpleExampleLineUtility : MonoBehaviour
{
public float tolerance = 1;
void Start()
{
// Get the points.
var lineRenderer = GetComponent<LineRenderer>();
int pointsBefore = lineRenderer.positionCount;
var points = new Vector3[pointsBefore];
lineRenderer.GetPositions(points);
// Simplify.
var simplifiedPoints = new List<Vector3>();
LineUtility.Simplify(points.ToList(), tolerance, simplifiedPoints);
// Assign back to the line renderer.
lineRenderer.positionCount = simplifiedPoints.Count;
lineRenderer.SetPositions(simplifiedPoints.ToArray());
Debug.Log("Line reduced from " + pointsBefore + " to " + lineRenderer.positionCount);
}
}
В следующем примере показано, как можно использовать параметр pointsToKeep для возврата списка индексов. Затем этот список можно использовать для упрощения линии, которая сохраняет точки в этом списке. К получившейся упрощенной линии можно добавить дополнительные точки.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
// This example shows how to use the pointsToKeep parameter to generate a new simplified version of the line.
[RequireComponent(typeof(LineRenderer))]
public class SimpleExampleLineUtilityPointsToKeep : MonoBehaviour
{
public float tolerance = 1;
void Start()
{
// Get the points.
var lineRenderer = GetComponent<LineRenderer>();
int pointsBefore = lineRenderer.positionCount;
var points = new Vector3[pointsBefore];
lineRenderer.GetPositions(points);
// Simplify.
var pointsToKeep = new List();
LineUtility.Simplify(points.ToList(), tolerance, pointsToKeep);
var simplifiedPoints = new Vector3[pointsToKeep.Count];
for (int i = 0; i < simplifiedPoints.Length; ++i)
{
simplifiedPoints[i] = points[pointsToKeep[i]];
}
// Assign back to the line renderer.
lineRenderer.positionCount = simplifiedPoints.Length;
lineRenderer.SetPositions(simplifiedPoints);
Debug.Log("Line reduced from " + pointsBefore + " to " + lineRenderer.positionCount);
}
}
В этом примере создается линия в форме синусоиды и предоставляется графический интерфейс для настройки параметров генерации и упрощения линии.
using System.Collections.Generic;
using UnityEngine;
// This example creates a sine wave and then simplifies it using the LineUtility.
// The parameters can be adjusted through an in game GUI to allow for experimentation.
[RequireComponent(typeof(LineRenderer))]
public class LineUtilityExample : MonoBehaviour
{
public int numberOfPoints = 1000;
public float length = 50;
public float waveHeight = 10;
public float tolerance = 0.1f;
private LineRenderer lineRenderer;
private List<Vector3> points = new List<Vector3>(); // Generated points before LineOptimizer is used.
private List<Vector3> simplifiedPoints = new List<Vector3>(); // Simplified points after LineOptimizer is used.
public void Start()
{
lineRenderer = GetComponent<LineRenderer>();
}
// Generates the sine wave points.
public void GeneratePoints()
{
points.Clear();
float halfWaveHeight = waveHeight * 0.5f;
float step = length / numberOfPoints;
for (int i = 0; i < numberOfPoints; ++i)
{
points.Add(new Vector3(i * step, Mathf.Sin(i * step) * halfWaveHeight, 0));
}
}
// Simplify the line using the LineOptimizer.
public void SimplifyLine()
{
simplifiedPoints.Clear();
LineUtility.Simplify(points, tolerance, simplifiedPoints);
lineRenderer.positionCount = simplifiedPoints.Count;
lineRenderer.SetPositions(simplifiedPoints.ToArray());
}
// Draw a simple GUI slider with a label.
private static float GUISlider(string label, float value, float min, float max)
{
GUILayout.BeginHorizontal(GUILayout.Width(Screen.width / 2.0f));
GUILayout.Label(label + "(" + value + ") :", GUILayout.Width(150));
var val = GUILayout.HorizontalSlider(value, min, max);
GUILayout.EndHorizontal();
return val;
}
public void OnGUI()
{
GUILayout.Label("LineUtility.Simplify", GUI.skin.box);
// We use GUI.changed to detect if a value was changed via the GUI, if it has we can then re-generate the points and simplify the line again.
GUI.changed = false;
numberOfPoints = (int)GUISlider("Number of Points", numberOfPoints, 0, 1000);
length = GUISlider("Length", length, 0, 100);
waveHeight = GUISlider("Wave Height", waveHeight, 0, 100);
if (GUI.changed)
GeneratePoints();
tolerance = GUISlider("Simplify Tolerance", tolerance, 0, 2);
if (GUI.changed)
SimplifyLine();
float percentRemoved = 100.0f - ((float)lineRenderer.positionCount / numberOfPoints) * 100.0f;
if (tolerance > 0.0f)
GUILayout.Label("Points after simplification: " + lineRenderer.positionCount + "(Removed " + percentRemoved.ToString("##.##") + "%)");
}
}