C # Разбить массив координат на большее расстояние между числами Z - PullRequest
0 голосов
/ 26 июня 2018

Я делаю лазерный сканер с винтовой пружиной для измерения, и лазер дает мне значения, только если он достигает этой пружины. Итак, у меня есть массив X, Z точек, таких как: "10,5; 11,6; 12,7; 11,8; 10,9; 10,15; 11,16; 12,17; 11,18; 10,19" и т. Д. Я надеюсь, что вы понимаете это - вот изображение этого explaining how laser measures spring

Как я могу разделить этот массив по "большому пространству в координатах Z" - как я могу отделить эти пружинные "вершины"? (Я не знаю, как это назвать: D) Я буду в порядке только с этими точками наибольшего диаметра Х (например, 12,7; 12,17).

РЕДАКТИРОВАТЬ: Я постараюсь объяснить больше. У меня есть массив X, Z точек (X это длина, Z это высота). Это выглядит так: {[10,5], [11,6], [12,7], [11,8], [10,9], [10,15], [11,16], [12 , 17], [11,18], [10,19]}. Запятая разделяет координаты X и Z (как на изображении). Мне нужно определить разрыв между этими группами точек - между [10,9] и [10,15], чтобы я мог рассчитать, сколько нитей у пружины - и получить только эти самые высокие точки X - [12,7] и [12,17]. Моя идея состояла в том, чтобы пройтись по этому массиву и проверить, меньше ли предыдущий Z, чем xx, но я не мог решить, что делать дальше. Я все еще изучаю C # и большую часть времени провожу поиск в Google и пробую, но для этого я даже не представлял, что и как попробовать: /

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Учитывая XZ класс как

public class XZ
{
    public int X { get; set; }
    public int Z { get; set; }

    public XZ(int x, int z)
    {
        X = x;
        Z = z;
    }

    public override string ToString()
    {
        return $"X = {X}, Z = {Z}";
    }
}

мы можем определить:

static IEnumerable<XZ[]> SplitByZGap(IEnumerable<XZ> points, int gap)
{
    var group = new List<XZ>();

    bool first = true;
    int lastZ = 0;

    foreach (var point in points)
    {
        if (first)
        {
            first = false;
        }
        else if (Math.Abs(point.Z - lastZ) >= gap)
        {
            var group2 = group.ToArray();
            group.Clear();
            yield return group2;
        }

        lastZ = point.Z;
        group.Add(point);
    }

    {
        var group2 = group.ToArray();
        group.Clear();
        yield return group2;
    }
}

Это разделит коллекцию XZ точек на "разрыв" (таким образом, расстояние по оси Z) * ​​1009 *

Мы можем определить некоторые данные как:

var points = new[]
{
    new XZ(10,5),
    new XZ(11,6),
    new XZ(12,7),
    new XZ(11,8),
    new XZ(10,9),
    new XZ(10,15),
    new XZ(11,16),
    new XZ(12,17),
    new XZ(11,18),
    new XZ(10,26),
};

(обратите внимание, что я изменил последнюю координату z с 19 на 26)

А потом:

var res = SplitByZGap(points, 6).ToArray();
0 голосов
/ 26 июня 2018

Простое использование String Split. Чтобы получить разрыв, посмотрите на наклон точек на отдельные циклы. Код ниже является одним из способов выполнения раскола. Вы не можете изменить порядок точек, как пример, который может не дать надлежащих результатов. Похоже, ваша картинка и список точек противоположны друг другу.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace ConsoleApplication1
{
    enum State
    {
        UNKNOWN,
        POSITIVE,
        NEGATIVE
    }
    class Program
    {
        static void Main(string[] args)
        {
            string input = "10,5; 11,6; 12,7; 11,8; 10,9; 10,15; 11,16; 12,17; 11,18; 10,19";
            string[] splitSemicolon = input.Split(new char[] { ';' });
            Point[] points = splitSemicolon.Select(x => x.Split(new char[] { ',' })).Select(x => new Point(int.Parse(x.FirstOrDefault()), int.Parse(x.LastOrDefault()))).ToArray();            

            State state = State.UNKNOWN;
            List<Cycle> cycles = new List<Cycle>();
            Cycle newCycle = null;
            for (int i = 1; i < points.Length; i++)
            {
                double slope = 0;
                if (points[i].X == points[i - 1].X)
                {
                    slope = points[i].Y - points[i - 1].Y;
                }
                else
                {
                    slope = (points[i].Y - points[i - 1].Y) / (points[i].X - points[i - 1].X);
                }
                switch (state)
                {
                    case State.UNKNOWN:
                        newCycle = new Cycle();
                        cycles.Add(newCycle);
                        if (slope < 0)
                        {
                            newCycle.negativeSlope = new List<Point> { points[0], points[1] };
                            state = State.NEGATIVE;
                        }
                        else
                        {
                            newCycle.positiveSlope = new List<Point> { points[0], points[1] };
                            state = State.POSITIVE;
                        }
                        break;

                    case State.POSITIVE :
                        if (slope > 0)
                        {
                            newCycle.positiveSlope.Add(points[i]);
                        }
                        else
                        {
                            newCycle = new Cycle();
                            cycles.Add(newCycle);
                            newCycle.negativeSlope = new List<Point>() { points[i] };
                            state = State.NEGATIVE;
                        }
                        break;
                    case State.NEGATIVE:
                        if (slope > 0)
                        {
                            newCycle.positiveSlope = new List<Point>() { points[i] };
                            state = State.POSITIVE;
                        }
                        else
                        {
                            newCycle.negativeSlope.Add(points[i]);
                        }
                        break;
                }
            }

        }
    }
    public class Cycle
    {
        public List<Point> negativeSlope { get; set; }
        public List<Point> positiveSlope { get; set; }
    }
}
...