Unity 6.3
0 онлайн 59 гостей 3 в системе
Вход

LineUtility.Simplify

Declaration

public static void Simplify(List<Vector3> points, float tolerance, List<int> pointsToKeep);
public static void Simplify(List<Vector3> points, float tolerance, List<Vector3> simplifiedPoints);
public static void Simplify(List<Vector2> points, float tolerance, List<int> pointsToKeep);
public static void Simplify(List<Vector2> points, float tolerance, List<Vector2> simplifiedPoints);

Параметры

Параметр Описание
пункты Точки, из которых состоит первоначальная линия.
допуск Это значение используется для оценки того, какие точки следует удалить с линии. Более высокое значение приводит к более простой линии (менее точек). Положительное значение, близкое к нулю, приводит к линии с небольшим или никаким сокращением. Значение 0 или меньше не имеет никакого эффекта.
pointsToKeep Заполняется этой функцией. Содержит индексы точек, которые должны быть генерированы в упрощенной версии.
simplifiedPoints Заполняется этой функцией. Содержит точки, которые образуют упрощенную линию.

Описание

Создает упрощенную версию первоначальной линии путем удаления точек, которые находятся в пределах указанного допуска.

Например, вы можете использовать эту функцию для уменьшения сложной линии, состоящей из тысяч точек. Линия может быть уменьшена до сотен или даже меньшего количества точек и в то же время сохранить форму, близкую к оригиналу. Вы можете создать несколько версий одной и той же линии с различными уровнями детализации, настроив допуски (более высокие значения допуска приводят к меньшему количеству точек в созданной линии). LODGroup система.

Алгоритм Simplify основан на Алгоритм Пьюкера ; она создаёт линию, которая близко повторяет исходную, но содержит меньше точек (их количество определяется допуском).

Примечание: Эта функция может обрабатывать большое количество точек, так как она не является рекурсивной. 2D версия этой функции работает лучше, чем эта функция, поскольку она использует более простой способ оценки точек.

Дополнительные ресурсы: 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<int>(); 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); } }

В этом примере генерируется линия в форме синусоидального волнения и предоставляется GUI для настройки параметров генерации и упрощения линии.

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("##.##") + "%)"); } }