Trójkąty

8. Wzór Picka

Wzór Picka to klasyczny wynik z geometrii dyskretnej, dotyczący wielokątów kratowych (czyli takich, których wszystkie wierzchołki leżą w punktach o współrzędnych całkowitych).

Mówi on, że dla takiego wielokąta: \[P=W+\frac{B}{2}-1\]

gdzie:

  • \(P\) – pole wielokąta,
  • \(W\) – liczba punktów kratowych wewnątrz wielokąta,
  • \(B\) – liczba punktów kratowych na brzegu wielokąt

Przykład
W poniższym wielokącie znajduje się 5 punktów kratowych, a na jego brzegi jest 6 punktów kratowych. 

czyli:
\(W = 5\)
\(B = 6\)

Korzystając ze wzoru Picka \(P=5+\frac{1}{2} \cdot 6 -1 = 5+3-1=7\).

 

Wzór Picka uszczegółowiony do trójkąta kratowego - wierzchołki trójkąta leżą w punktach o współrzędnych całkowitych, nie zmienia swojej postaci, innymi słowy dalej możemy skorzystać ze wzoru:

\[P=W+\frac{B}{2}-1\]

gdzie:

  • \(P\) – pole wielokąta,
  • \(W\) – liczba punktów kratowych wewnątrz wielokąta,
  • \(B\) – liczba punktów kratowych na brzegu wielokąt

 

Przykład
Weźmy trójkąt prostokątny o wierzchołkach: \((0,0)\), \((0,4)\), \((3,0)\). 

Punktów wewnątrz trójkąta jest \(3\)
Punktów na krawędzi jest \(8\).

Podstawiamy do wzoru Picka: \(P=3+\frac{1}{2}\cdot 8-1 = 3+4-1=6\).

 

Wzór na pole dowolnego trójkąta kratowego

przy pomocy Picka (czyli w postaci zależnej tylko od punktów na bokach)

Rozważmy trójkąt kratowy o wierzchołkach \(A\), \(B\), \(C\) w punktach o współrzędnych całkowitych.

Każdy bok trójkąta jest odcinkiem między dwoma punktami kratowymi. Liczbę punktów kratowych na odcinku między punktami \(A=(x_A, y_A)\), \(B=(x_B,y_B)\) można znaleźć ze wzoru:

\[B_{AB}=gcd(|x_B-x_A|, |y_B-y_A|)+1\], gdzie \(gcd\), to największy wspólny dzielnik.

Czyli liczba punktów na wszystkich bokach trójkata jest równa

\[B=B_{AB}+B_{AB}+B_{BC}+B_{CA}-3\]

Ostateczny wzór Picka dla trójkąta

\[P=W+\frac{1}{2}(gcd(|x_B-x_A|, |y_B-y_A|)+ |x_C-x_B|, |y_C-y_B|) + |x_A-x_C|, |y_A-y_C|))-1\]

 

Python C++
# Program: Pole trójkąta z użyciem wzoru Picka
# Autor: Jarosław Drzeżdżon
# Data: 2025-09-17

from math import gcd

def pick_triangle_area(A, B, C, I):
    """
    Oblicza pole trójkąta kratowego za pomocą wzoru Picka.
    
    A, B, C: wierzchołki trójkąta w postaci (x, y)
    W: liczba punktów kratowych wewnątrz trójkąta
    """
    # Liczba punktów na bokach
    B_AB = gcd(abs(B[0]-A[0]), abs(B[1]-A[1])) + 1
    B_BC = gcd(abs(C[0]-B[0]), abs(C[1]-B[1])) + 1
    B_CA = gcd(abs(A[0]-C[0]), abs(A[1]-C[1])) + 1
    
    # Całkowita liczba punktów na brzegu
    B_total = B_AB + B_BC + B_CA - 3
    
    # Pole ze wzoru Picka
    P = I + B_total / 2 - 1
    return P

# Przykład
A = (0, 0)
B = (4, 0)
C = (0, 3)
I = 3  # liczba punktów wewnętrznych

pole = pick_triangle_area(A, B, C, I)
print("Pole trójkąta kratowego:", pole)
// Pole trójkąta z użyciem wzoru Picka
// Autor: Jarosław Drzeżdżon
// Data: 2025-09-17

#include <iostream>
#include <cmath>

using namespace std;

// Funkcja do obliczenia największego wspólnego dzielnika
int gcd(int a, int b)
{
    while (b != 0)
    {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// Funkcja do obliczenia pola trójkąta kratowego ze wzoru Picka
double pick_triangle_area(pair<int, int> A, pair<int, int> B, pair<int, int> C, int I)
{
    int B_AB = gcd(abs(B.first - A.first), abs(B.second - A.second)) + 1;
    int B_BC = gcd(abs(C.first - B.first), abs(C.second - B.second)) + 1;
    int B_CA = gcd(abs(A.first - C.first), abs(A.second - C.second)) + 1;

    int B_total = B_AB + B_BC + B_CA - 3;

    double P = I + B_total / 2.0 - 1;
    return P;
}

int main()
{
    pair<int, int> A = {0, 0};
    pair<int, int> B = {4, 0};
    pair<int, int> C = {0, 3};
    int I = 3;

    double pole = pick_triangle_area(A, B, C, I);
    cout << "Pole trojkata kratowego: " << pole << endl;

    return 0;
}

Efekt wykonania kodu programu:

0 0
0 3
4 0 
Pole trójkąta 6.00