Расстояние между точками на замкнутой кривой

Автор urbaraban, 14.05.19, 13:07:10

« предыдущая - следующая »

0 Пользователей и 1 гость просматривают эту тему.

urbaraban

Доброго дня.

Я думаю вы уже догадались что расстояние между точками на замкнутой кривой может считаться как в одну, так и в другую сторону. И я уже сломал себе голову над тем что бы понять принцип, по которому функция ksDistancePntPntOnCurve определяет направление.

Компас 16.1 х64
В коде нет ничего принципиально интересного, схема типа:


IContour contur1;
IContour contur2;
if (mat.ksIntersectCurvCurv(contour1.Reference, contour2.Reference, arrayCurve) == 1)
{
  for(int i = 1; i < arrayCurve.Count; i++)
  {
     shovTemp += mat.ksDistancePntPntOnCurve(contour2.Reference, point[i - 1].x, point[i - 1].y, point[i].x, point[i].y);
  }
}


Ладно бы целиком цикл считался в одну сторону, но проблема в том что даже в одном цикле в какой-то момент можно получить значение в обратном направлении.

Ну и попутный вопрос: Есть ли функция определения попадания точки на кривую?

Sabahs

ksIsPointInsideContour - Проверить положение точки относительно кривой.

urbaraban

Странно, но у меня нет такой функции в ksMathematic2D, хотя по хелпу она вроде оттуда.

По первому вопросу нашлась некоторая закономерность и судя по всему измерения идут по часовой стрелке, хотя перемена мест между точками в функции не дает изменения результата.

У контура есть нулевая точка, то есть точка с которой начинается строиться объект.

IContourSegment pDrawObj = (IContourSegment)contour.Segment[0];
IContourLineSegment contourLineSegment = (IContourLineSegment)pDrawObj;
BeginPoint.x = contourLineSegment.X1;
BeginPoint.y = contourLineSegment.Y1;


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

На самом деле я не уверен что правильно описал или понял, но приведу костыль что пока работает:

for (int j = 1; j < point.Length; j++)
{
   if ((point[j].x != 0) && (point[j].y != 0))
   {
         if ((Math.Round(point[j - 1].x, 2) != Math.Round(point[j].x, 2)) || (Math.Round(point[j - 1].y, 2) != Math.Round(point[j].y, 2)))
           {
               if (mat.ksEqualPoints(point[j - 1].x, point[j - 1].y, BeginPoint.x, BeginPoint.y) == 1)
                   shovTemp += mat.ksDistancePntPntOnCurve(contour1.Reference, point[j - 1].x, point[j - 1].y, point[j].x, point[j].y);
               else
                   shovTemp += mat.ksDistancePntPntOnCurve(contour2.Reference, point[j - 1].x, point[j - 1].y, point[j].x, point[j].y);
            }

    }
}

Sabahs

Интерфейс - ksDocument2D или API экспортных функций.

urbaraban

Ну если кто-то столкнется с такой проблемой то задачу я решил русурсоемко, но работает:


for (int j = 0; j < points.Length; j++)    //где points это точки пересечения двух контуров
     for (int k = j + 1; k < points.Length; k++) //и мы сравниваем каждую с каждой, так как массив к нам приходит не по порядку, а совершенно в разнобой и сортировать его по удаленности от базовой точки, к примеру, так же затратно.
      {
         double P1 = mat.ksGetCurvePerimeter(contour1.Reference, 1);        //Периметр фигуры1
         double P2 = mat.ksGetCurvePerimeter(contour2.Reference, 1);         //Периметр фигуры2
         double L1 = mat.ksDistancePntPntOnCurve(contour1.Reference, points[j].x, points[j].y, points[k].x, points[k].y); //Длинна между точками по фигуре1
         double L2 = mat.ksDistancePntPntOnCurve(contour2.Reference, points[j].x, points[j].y, points[k].x, points[k].y);  //по фигуре2
                                           
         //Тут работает логика исключений
         if ((Math.Round(P1 - L1, 2) == Math.Round(L2, 2)))     //Если измерение у одного контура ошибочно
         {
                if (L2 > lenthTemp) lenthTemp = L2; }
                else if ((Math.Round(L2, 2) == Math.Round(L1, 2)))     //Если оба правильны
                { if (L1 > lenthTemp) lenthTemp = L1; }
                 else if ((Math.Round(P2 - L2, 2) == Math.Round(P1 - L1, 2)))   ///Если оба ошибочны
                 { if (P1 - L1 > lenthTemp) lenthTemp = P1 - L1; }

}