Внутренний угол между двумя линиями

, если это значение maxJsonLength является int, то насколько велико его int 32bit / 64bit / 16bit .... Я просто хочу быть уверенным, какое максимальное значение я могу установить как my maxJsonLength

<scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
        </webServices>
    </scripting>
13
задан dandan78 24 September 2015 в 01:19
поделиться

6 ответов

Я думаю, что вы ищете внутреннее произведение (вы также можете просмотреть запись скалярное произведение ) двух углов. В вашем случае это дает:

float dx21 = x2-x1;
float dx31 = x3-x1;
float dy21 = y2-y1;
float dy31 = y3-y1;
float m12 = sqrt( dx21*dx21 + dy21*dy21 );
float m13 = sqrt( dx31*dx31 + dy31*dy31 );
float theta = acos( (dx21*dx31 + dy21*dy31) / (m12 * m13) );

Ответ в радианах.

РЕДАКТИРОВАТЬ: Вот полная реализация. Замените проблемные значения в p1, p2 и p3 и дайте мне знать, что вы получите. Точка p1 - это вершина, в которой две прямые пересекаются, в соответствии с вашим определением двух прямых.

#include <math.h>
#include <iostream>

template <typename T> class Vector2D
{
private:
    T x;
    T y;

public:
    explicit Vector2D(const T& x=0, const T& y=0) : x(x), y(y) {}
    Vector2D(const Vector2D<T>& src) : x(src.x), y(src.y) {}
    virtual ~Vector2D() {}

    // Accessors
    inline T X() const { return x; }
    inline T Y() const { return y; }
    inline T X(const T& x) { this->x = x; }
    inline T Y(const T& y) { this->y = y; }

    // Vector arithmetic
    inline Vector2D<T> operator-() const
        { return Vector2D<T>(-x, -y); }

    inline Vector2D<T> operator+() const
        { return Vector2D<T>(+x, +y); }

    inline Vector2D<T> operator+(const Vector2D<T>& v) const
        { return Vector2D<T>(x+v.x, y+v.y); }

    inline Vector2D<T> operator-(const Vector2D<T>& v) const
        { return Vector2D<T>(x-v.x, y-v.y); }

    inline Vector2D<T> operator*(const T& s) const
        { return Vector2D<T>(x*s, y*s); }

    // Dot product
    inline T operator*(const Vector2D<T>& v) const
        { return x*v.x + y*v.y; }

    // l-2 norm
    inline T norm() const { return sqrt(x*x + y*y); }

    // inner angle (radians)
    static T angle(const Vector2D<T>& v1, const Vector2D<T>& v2)
    {
        return acos( (v1 * v2) / (v1.norm() * v2.norm()) );
    }
};

int main()
{
    Vector2D<double> p1(215, 294);
    Vector2D<double> p2(174, 228);
    Vector2D<double> p3(303, 294);

    double rad = Vector2D<double>::angle(p2-p1, p3-p1);
    double deg = rad * 180.0 / M_PI;

    std::cout << "rad = " << rad << "\tdeg = " << deg << std::endl;

    p1 = Vector2D<double>(153, 457);
    p2 = Vector2D<double>(19, 457);
    p3 = Vector2D<double>(15, 470);

    rad = Vector2D<double>::angle(p2-p1, p3-p1);
    deg = rad * 180.0 / M_PI;

    std::cout << "rad = " << rad << "\tdeg = " << deg << std::endl;

    return 0;
}

Приведенный выше код дает:

rad = 2.12667   deg = 121.849
rad = 0.0939257 deg = 5.38155
20
ответ дан 25 October 2019 в 20:16
поделиться

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

0
ответ дан 25 October 2019 в 20:16
поделиться
if (result > 180)
{
     result = 360 - result;
}

Таким образом, это всегда будет внутренний угол. Просто добавьте его после получения результата.

4
ответ дан 25 October 2019 в 20:16
поделиться

Надеюсь, я правильно понял ваш вопрос, поскольку мне нужен острый угол, а не тупой угол пересечения двух линий. Я прав?

Острый и тупой углы пересечения дополняют друг друга на 180 градусов.то есть

 acute + obtuse = PI.

http://www.mathworks.com/access/helpdesk/help/techdoc/ref/atan.html показывает, что атан асимптотичен при +/- pi / 2.

Следовательно, максимальная разница между двумя результатами атана равна пи или 180 градусов, независимо от того, используете ли вы нотацию +/- или положительную нотацию от 0 до пи градиента.

Рассмотрим следующий псевдокод:

acuteAngle(m1, m2){
  a = atan(m1) - atan(m2);

  // if obtuse get the complementary acute angle:
  if (a>PI/2) 
    a = PI - a;
  return a;
} 

Функция sharpAngle математически иллюстрирует, что вам нужно сделать.

Однако его нельзя использовать для значений углов в окрестности PI / 2, потому что двоичное сравнение углов с результатами в этой окрестности вызывает сомнения, представлен ли тупой или острый угол.

Следовательно, мы должны сравнить координаты точек двух прямых. Мы выясняем, является ли 3-я линия, образованная из [(x2, y2) (x3, y3)] , короче, равна или длиннее гипотетической гипотенузы.

В силу теоремы Пифагора Гипотенуза образуется, если угол составляет точно PI / 2 или 90 градусов. Назовем его гипотетическую линию гипотенузы L3Hypo.

Путем геометрической визуализации в уме,

  • Если 3-я линия длиннее, чем L3Hypo, угол тупой.
  • Если короче, угол острый.
  • В противном случае - идеальное 90.

Следовательно,

L1.lengthSquared = sq(x2-x1) + sq(y2-y1)
L2.lengthSquared = sq(x3-x1) + sq(y3-y1)
L3Hypo.lengthSquared = L1.lengthSquared + L2.lengthSquared
L3.lengthSquared = sq(x3-x2) + sq(y3-y2)

Следовательно, следующий псевдокод,

struct Point{
  double x, y;
}

// no need to struct, for clarity only
struct Line{
  double lengthSquared;
}

#define sq(n) (n*n)
int isObtuse(Point P1, P2, P3){
  Line L1, L2, L3, L3Hypo;

  L1.lengthSquared = sq(P2.x-P1.x) + sq(P2.y-P1.y);
  L2.lengthSquared = sq(P3.x-P1.x) + sq(P3.y-P1.y);
  L3Hypo.lengthSquared = L1.lengthSquared + L2.lengthSquared;
  L3.lengthSquared = sq(P3.x-P2.x) + sq(P3.y-P2.y);

  if (L3>L3Hypo) return 1; //obtuse
  else if (L3<L3Hypo) return -1; //acute
  else return 0;
}

Предполагая, что у вас уже есть функция getGradient (Point P, Q):

double m1m2 = getGradient(P1,P2);
double m1m3 = getGradient(P1,P3);
double a = Abs(atan(m1m2) - atan(m1m3));
if (isObtuse(P1, P2, P3)>0)
  a = PI - a;

Возможно, я допустил несколько опечаток в псевдокоде (надеюсь, нет), но я продемонстрировал суть концепции. Если так, кто-нибудь может быть так любезен, чтобы отредактировать опечатки.

Далее Однако, поразмыслив над этим, я обнаружил, что борьба за точность сводится к ее самому слабому звену из-за директивы

#define PI 3.14159blah..blah..blah.

Итак, мы могли бы также избавить от всех проблем и просто сделать следующее:

double m1m2 = getGradient(P1,P2);
double m1m3 = getGradient(P1,P3);
double a = Abs(atan(m1m2) - atan(m1m3));
double b = PI - a;
return min(a, b);//the smaller of the two is the acute
0
ответ дан 25 October 2019 в 20:16
поделиться

Внутренний угол между двумя векторами (v1, v2) = arc cos ( внутреннее произведение(v1,v2) / (модуль(v1) * модуль(v2)) ).

Где внутреннее произведение(v1,v2) = xv1*xv2 + yv1*yv2

модуль(v) = sqrt(pow(xv,2) + pow(yv,2))

Итак, ответ на ваш вопрос реализован на следующем примере:

#define PI   3.14159258

int main()
{
    double x1,y1,x2,y2,y3;
    double m1, m2;
    double mod1, mod2, innerp, angle;

    cout << "x1 :";
    cin >> x1;
    cout << "y1 :";
    cin >> y1;
    cout << "x2 :";
    cin >> x2;
    cout << "y2 :";
    cin >> y2;
    cout << "y3 :";
    cin >> y3;

    m1 = atan((y2-y1)/(x2-x1)) * 180 / PI;
    m2 = atan((y3-y1)/(x2-x1)) * 180 / PI;

    mod1   = sqrt(pow(y2-y1,2)+pow(x2-x1,2));
    mod2   = sqrt(pow(y3-y1,2)+pow(x2-x1,2));
    innerp = (x2-x1)*(x2-x1) + (y2-y1)*(y3-y1);
    angle  = acos(innerp / (mod1 * mod2)) * 180 / PI;

    cout << "m1 : " << m1 << endl;
    cout << "m2 : " << m2 << endl;
    cout << "angle : " << angle << endl;
}
1
ответ дан 25 October 2019 в 20:16
поделиться

Вся суть гораздо проще, чем приведенные ответы:

При использовании atan(slope) вы теряете (буквально) один бит информации, то есть существует ровно два угла (theta) и (theta+PI) в диапазоне (0..2*PI), которые дают одинаковое значение для функции tan().

Просто используйте atan2(deltax, deltay), и вы получите прямой угол. Например

atan2(1,1) == PI/4
atan2(-1,-1) == 5*PI/4

Затем вычтите, возьмите абсолютное значение, и если больше PI, вычтите из 2*PI.

1
ответ дан 25 October 2019 в 20:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: