LearnToCP
Prijavi se
Navigacija
PočetnaRoad-mapaProblemiO Nama
Teorija
Takmičarsko Znanje
Izbor Radnog Okruženja (IDE)
Osnove
Tvoj Prvi ProgramTipovi podataka, Unos i IzlazC++ sintaksaModuloFunkcijeVektoriMatriceVremenska Složenost Algoritma
Sortiranje
SortiranjeSortiranje PrebrojavanjemRadix Sort
Tehnike Optimizacije
Dva PokazivačaZbir brojeva od 1 do nZbir PrefiksaBinarna PretragaPohlepni AlgoritmiFunkcije Binarne PretrageBinarna Pretraga po RešenjuPodeli, pa Vladaj
Binarni Brojevi
Binarni BrojeviBrojevi u koduOperacije nad BitovimaBitmaske
Matematika
Binarno StepenovanjeProsti BrojeviRastavljanje na proste činioceNZD i NZSEratostenovo SitoModifikovano Sito
Strukture Podataka
Niske (Stringovi)StekRedMapeSkupovi (Set)Red sa PrioritetomKorišćenje Proizvoljnih KriterijumaSegmentna StablaFenvikova StablaSparse TabeleDisjunktni Skupovi
Kombinatorika
Pravilo SabiranjaPravilo MnoženjaKombinatorni ObjektiPrincip Uključenja Isključenja
Geometrija
Osnove GeometrijeVektoriVektorski i Skalarni ProizvodLinijePoligoniUgloviTačka u PoligonuRastojanja i Tačke PresekaKonveksni OmotačKrugovi
Rekurzija
PokazivačiRekurzijaGenerisanje Kombinatornih Objekata
Dinamičko Programiranje
O DP-uDP nad StablimaDP nad BitmaskamaDP nad brojevima
Teorija Grafova
GrafoviDFS i BFSNajkraći PuteviStablaTopološko SortiranjeDajkstrin AlgoritamMinimalna Razapinjuća StablaAlgoritmi Najkraćih Puteva
Napredna Teorija Grafova
Dvostruka PovezanostJako Povezane KomponenteBipartitni GrafMaksimalni Protok u GrafuFord-Fulkersonov AlgoritamDualnost Protoka i Minimalnog PresekaTeško-Laka DekompozicijaCentroidna Dekompozicija
Napredne Strukture Podataka
2D i 3D Segmentna StablaLenjo PropagiranjeImplicitna Segmentna StablaPerzistentna Segmentna StablaNajbliži Zajednički PredakTrieBalansirana Binarna Stabla PretrageMoov Algoritam

Uglovi

U ovoj lekciji prestajemo da pitamo sa koje strane prave je nešto i pitamo za sam ugao.

Dva načina da se zapiše isti ugao

Skalarni proizvod u sebi krije ugao:

a⋅b=∣a∣∣b∣cosθ

a vektorski proizvod krije isti taj ugao, samo preko sinusa:

a×b=∣a∣∣b∣sinθ

Podelimo drugi prvim i obe dužine se skrate, ostaje tanθ. Za razmotavanje toga služi baš atan2, a pošto prima dva dela odvojeno, pogađa i kvadrant:

θ=atan2(a×b,a⋅b)

Rezultat je u intervalu (−π,π] i ima znak - pozitivan je kada je b suprotno od kazaljke na satu u odnosu na a, po istom pravilu koje nam je dala orijentacija.
Da bismo ga pretvorili u stepene, množimo ga sa: 180.0 / acos(-1.0);

Vektori a i b sa uglom theta između njih sa leve strane, precrtani sa desne kao pravougli trougao čija je horizontalna kateta skalarni proizvod 9 a vertikalna vektorski proizvod 9, što daje ugao theta od 45 stepeni

Implementacija

Prostije rečeno, imamo funkciju koja nam, kada joj damo vektorski i skalarni proizvod, vraća ugao.

Angles.cpp
#include <bits/stdc++.h>

using namespace std;

struct v{

    long long x, y;
};

long long cross(v a, v b){

    return (a.x * b.y) - (a.y * b.x);
}

long long dot(v a, v b){

    return (a.x * b.x) + (a.y * b.y);
}

double angle(v a, v b){ //ugao sa znakom od a do b, u stepenima

    return atan2((double)cross(a, b), (double)dot(a, b)) * 180.0 / acos(-1.0);
}

int main(){

    cout<<fixed<<setprecision(1);

    cout<<angle({1, 0}, {0, 1})<<'\n';
    cout<<angle({1, 0}, {-1, 0})<<'\n';
    cout<<angle({0, 1}, {1, 0})<<'\n';
    cout<<angle({3, 0}, {3, 3})<<'\n';

    return 0;
}

Output:
90.0
180.0
-90.0
45.0

Ovo je prvo mesto u poglavlju gde izlazimo iz celih brojeva. Kada zadatak pita samo koji je od dva ugla veći, vektorski proizvod na to odgovara tačno - za atan2 posegni kada je sam ugao deo odgovora.