ARC по часовой стрелке или против часовой стрелки в SVG?

Мне нужно нарисовать дугу между двумя точками на краю круга. Предполагая, что дуга всегда рисуется на кратчайшем возможном расстоянии (edit2: флаг развертки установлен на 0), мне нужно знать, рисуется ли дуга по часовой стрелке или против часовой стрелки.

Я получил следующие входные данные:

  1. начальная точка (точка1)
  2. конечная точка (точка2)
  3. Центральная точка
  4. радиус

ARC по часовой стрелке или против часовой стрелки в SVG?

Edit1: этот вопрос связан с дугами в svg. Следовательно, это относится к программированию.

как это вообще связано с программированием? О какой геометрической библиотеке вы говорите? Где твой код?

MakePeaceGreatAgain 29.03.2022 10:53

Я голосую за то, чтобы закрыть этот вопрос, потому что он не о программировании, а чисто о математике/геометрии (при этом: проведите линию через центр и точку 1 и посмотрите, на какой стороне линии находится точка 2)

Franz Gleichmann 29.03.2022 10:54

SVG не определяет CW/CCW эллиптической дуги, вместо этого он определяется как комбинация флагов larc/sweep вместе с конечными точками вашей эллиптической дуги, поэтому ответ: дуги могут быть как CW, так и CCW, в зависимости от случая, для получения дополнительной информации см.: Преобразование дуги svg в линии .. поэтому, как только вы получите реальный центр дуги, вы можете использовать перекрестное произведение для определения направления по часовой и против часовой стрелки вашей дуги.

Spektre 29.03.2022 12:29

@FranzGleichmann речь идет о формате файла svg ...

Spektre 29.03.2022 12:29

@MakePeaceGreatAgain специфичен для представления эллиптических дуг в формате файла SVG ... ни код, ни библиотека для этого не важны ...

Spektre 29.03.2022 12:32

но этот сайт посвящен проблемам программирование, а не форматам файлов

MakePeaceGreatAgain 29.03.2022 12:39

Найдите знак векторного произведения векторов point1-center и point2-center, чтобы выявить ориентацию кратчайшей дуги

MBo 29.03.2022 12:45

@MakePeaceGreatAgain возникает вопрос при рисовании дуг в svg. Следовательно, это вопрос программирования.

shaaaa 29.03.2022 13:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
67
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ заключается в том, что SVG поддерживает дуги как по часовой, так и против часовой стрелки. Вы переключаетесь между ними, изменяя флаг «развертки» в команде дуги (A).

Если вы хотите узнать, как работают дуги SVG, обратите внимание на файл Раздел дуг дуг спецификации SVG.

флаг развертки всегда равен 0 в моей проблеме

shaaaa 29.03.2022 15:52

Играйте с дугами в: yqnn.github.io/svg-путь-редактор

Danny '365CSI' Engelman 29.03.2022 16:48

Описав данные, можно определить, какая дуга меньше - против часовой стрелки или по часовой стрелке.

Просто проверьте знак векторного произведения векторов point1-center и point2-center, чтобы определить ориентацию кратчайшей дуги:

cp = (p1.x-c.x)*(p2.y-c.y)-(p1.y-c.y)*(p2.x-c.x)

Для cp>0 вы должны установить параметр sweep на 0, в противном случае на 1 (возможно, наоборот), в то время как large-arc-flag всегда должен быть 0.

не уверен, как это скажет, если дуга по часовой стрелке или против часовой стрелки, вот в чем вопрос. Флаг развертки всегда равен 0

shaaaa 29.03.2022 16:10

Ваш вопрос касался возможно кратчайшее расстояние. Этот подход показывает, какое направление дает более короткую дугу.

MBo 29.03.2022 16:12

Пожалуйста, внимательно прочитайте заголовок и вопрос. Спасибо :)

shaaaa 30.03.2022 13:25

Вопрос говорит, что вы должны нарисовать дугу. Это правда?

MBo 30.03.2022 16:03
Ответ принят как подходящий

После обсуждения с математиком я нашел ответ на этот вопрос и на его основе написал следующий код:

public static bool IsClockWise(Point point1, Point point2, Circle circle)
        {
            var dxPoint1 = point1.X - circle.CenterX;
            var dyPoint1 = point1.Y - circle.CenterY;
            var dxPoint2 = point2.X - circle.CenterX;
            var dyPoint2 = point2.Y - circle.CenterY;


            double thetaPoint1 = 0, thetaPoint2 = 0;
            if (dxPoint1 > 0 && dyPoint1 >= 0)
                thetaPoint1 = Math.Asin(dyPoint1 / circle.Radius);
            else if (dxPoint1 <= 0 && dyPoint1 > 0)
                thetaPoint1 = Math.PI - Math.Asin(dyPoint1 / circle.Radius);
            else if (dxPoint1 < 0 && dyPoint1 <= 0)
                thetaPoint1 = Math.Abs(Math.Asin(dyPoint1 / circle.Radius)) + Math.PI;
            else if (dxPoint1 >= 0 && dyPoint1 < 0)
                thetaPoint1 = 2 * Math.PI - Math.Abs(Math.Asin(dyPoint1 / circle.Radius));

            if (dxPoint2 > 0 && dyPoint2 >= 0)
                thetaPoint2 = Math.Asin(dyPoint2 / circle.Radius);
            else if (dxPoint2 <= 0 && dyPoint2 > 0)
                thetaPoint2 = Math.PI - Math.Asin(dyPoint2 / circle.Radius);
            else if (dxPoint2 < 0 && dyPoint2 <= 0)
                thetaPoint2 = Math.Abs(Math.Asin(dyPoint2 / circle.Radius)) + Math.PI;
            else if (dxPoint2 >= 0 && dyPoint2 < 0)
                thetaPoint2 = 2 * Math.PI - Math.Abs(Math.Asin(dyPoint2 / circle.Radius));

            if (thetaPoint1 > thetaPoint2)
            {
                return !(thetaPoint1 - thetaPoint2 <= Math.PI);
            }

            return thetaPoint2 - thetaPoint1 <= Math.PI;

        }

OMG ... Вы пробовали простое выражение из моего ответа?

MBo 04.04.2022 07:01

Другие вопросы по теме