Quindi voglio calcolare il numero di punti all'interno di un dato triangolo. So che devo usare il Teorema di Pick, ma il mio codice finisce per essere ridicolmente lungo con la quantità di if-else se le dichiarazioni da testare per ogni caso. Sto usando questo come una guida How many integer points within the three points forming a triangle?, ma poi alla fine con questa (. Vertici è un array di array 3 Ogni array è (x, y) coordinate di un vertice del triangolo):Come utilizzare il teorema di Pick su qualsiasi triangolo dato
int maxX = Math.max(Math.max(vertices[0][0], vertices[1][0]), vertices[2][0]),
minX = Math.min(Math.min(vertices[0][0], vertices[1][0]), vertices[2][0]),
maxY = Math.max(Math.max(vertices[0][1], vertices[1][1]), vertices[2][1]),
minY = Math.min(Math.min(vertices[0][1], vertices[1][1]), vertices[2][1]);
int height = Math.abs(maxY - minY),
width = Math.abs(maxX - minX);
double area = Math.abs(((vertices[0][0] * (vertices[1][1] - vertices[2][1]
)) + (vertices[1][0] * (vertices[2][1] - vertices[0][1]))
+ vertices[2][0] * (vertices[0][1] - vertices[1][1]))/2);
if ((vertices[0][0] == vertices[1][0]) && (vertices[0][1] == vertices[2][1]))
{
area = ((Math.abs(vertices[0][1] - vertices[1][1]) - 1) *
(Math.abs(vertices[0][0] - vertices[2][0]) - 1))/2;
}
else if ((vertices[0][0] == vertices[2][0]) && (vertices[0][1] == vertices[1][1]))
{
area = ((Math.abs(vertices[0][1] - vertices[2][1]) - 1) *
(Math.abs(vertices[0][0] - vertices[1][0]) - 1))/2;
}
else if ((vertices[1][0] == vertices[2][0]) && (vertices[1][1] == vertices[0][1]))
{
area = ((Math.abs(vertices[1][1] - vertices[2][1]) - 1) *
(Math.abs(vertices[1][0] - vertices[0][0]) - 1))/2;
}
else if ((vertices[1][0] == vertices[2][0]) && (vertices[1][1] == vertices[0][1]))
{
area = ((Math.abs(vertices[1][1] - vertices[2][1]) - 1) *
(Math.abs(vertices[1][0] - vertices[0][0]) - 1))/2;
}
else if(vertices[0][0] == vertices[1][0])
{
int b = Math.abs(vertices[0][1] - vertices[1][1]);
/*double dist1 = Math.sqrt(Math.pow(vertices[0][0] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2)),
dist2 = Math.sqrt(Math.pow(vertices[1][0] - vertices[2][0], 2) +
Math.pow(vertices[1][1] - vertices[2][1], 2));*/
if (vertices[0][1] > vertices[1][1])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist1*/)/2) - (((width - 1) * (height - b - 1)
/*- dist2*/)/2);
}
else if (vertices[0][1] < vertices[1][1])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist2*/)/2) - (((width - 1) * (height - b - 1)
/*- dist1*/)/2);
}
}
else if(vertices[0][0] == vertices[2][0])
{
int b = Math.abs(vertices[0][1] - vertices[2][1]);
/*double dist1 = Math.sqrt(Math.pow(vertices[0][0] - vertices[1][0], 2) +
Math.pow(vertices[0][1] - vertices[1][1], 2)),
dist2 = Math.sqrt(Math.pow(vertices[2][0] - vertices[1][0], 2) +
Math.pow(vertices[2][1] - vertices[1][1], 2));*/
if (vertices[0][1] > vertices[2][1])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist1*/)/2) - (((width - 1) * (height - b - 1)
/*- dist2*/)/2);
}
else if (vertices[0][1] < vertices[2][1])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist2*/)/2) - (((width - 1) * (height - b - 1)
/*- dist1*/)/2);
}
}
else if(vertices[1][0] == vertices[2][0])
{
int b = Math.abs(vertices[1][1] - vertices[2][1]);
/*double dist1 = Math.sqrt(Math.pow(vertices[1][0] - vertices[0][0], 2) +
Math.pow(vertices[1][1] - vertices[0][1], 2)),
dist2 = Math.sqrt(Math.pow(vertices[2][0] - vertices[0][0], 2) +
Math.pow(vertices[2][1] - vertices[0][1], 2));*/
if (vertices[1][1] > vertices[2][1])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist1*/)/2) - (((width - 1) * (height - b - 1)
/*- dist2*/)/2);
}
else if (vertices[1][1] < vertices[2][1])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist2*/)/2) - (((width - 1) * (height - b - 1)
/*- dist1*/)/2);
}
}
else if(vertices[0][1] == vertices[1][1])
{
int b = Math.abs(vertices[0][0] - vertices[1][0]);
/*double dist1 = Math.sqrt(Math.pow(vertices[0][1] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2)),
dist2 = Math.sqrt(Math.pow(vertices[1][0] - vertices[2][0], 2) +
Math.pow(vertices[1][1] - vertices[2][1], 2));*/
if (vertices[0][0] > vertices[1][0])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist1*/)/2) - (((width - 1) * (height - b - 1)
/*- dist2*/)/2);
}
else if (vertices[0][0] < vertices[1][0])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist2*/)/2) - (((width - 1) * (height - b - 1)
/*- dist1*/)/2);
}
}
else if(vertices[0][1] == vertices[2][1])
{
int b = Math.abs(vertices[0][0] - vertices[2][0]);
/*double dist1 = Math.sqrt(Math.pow(vertices[0][1] - vertices[1][0], 2) +
Math.pow(vertices[0][1] - vertices[1][1], 2)),
dist2 = Math.sqrt(Math.pow(vertices[2][0] - vertices[1][0], 2) +
Math.pow(vertices[2][1] - vertices[1][1], 2));*/
if (vertices[0][0] > vertices[2][0])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist1*/)/2) - (((width - 1) * (height - b - 1)
/*- dist2*/)/2);
}
else if (vertices[0][0] < vertices[2][0])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist2*/)/2) - (((width - 1) * (height - b - 1)
/*- dist1*/)/2);
}
}
else if(vertices[1][1] == vertices[2][1])
{
int b = Math.abs(vertices[1][0] - vertices[2][0]);
/*double dist1 = Math.sqrt(Math.pow(vertices[1][1] - vertices[0][0], 2) +
Math.pow(vertices[1][1] - vertices[0][1], 2)),
dist2 = Math.sqrt(Math.pow(vertices[2][0] - vertices[0][0], 2) +
Math.pow(vertices[2][1] - vertices[0][1], 2));*/
if (vertices[1][0] > vertices[2][0])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist1*/)/2) - (((width - 1) * (height - b - 1)
/*- dist2*/)/2);
}
else if (vertices[1][0] < vertices[2][0])
{
area = (width - 1) * (height - 1) /*- dist1 - dist2*/ - (((width - 1) *
(height - 1) /*- dist2*/)/2) - (((width - 1) * (height - b - 1)
/*- dist1*/)/2);
}
}
else if (minX == vertices[0][0])
{
int a = 0,
b = 0;
/*double dist1 = 0,
dist2 = 0,
dist3 = 0;*/
if(Math.min(vertices[1][0], vertices[2][0]) == vertices[1][0])
{
a = width - (vertices[1][0] - vertices[0][0]);
b = height - (vertices [1][1] - vertices[0][1]);
/*dist1 = Math.sqrt(Math.pow(vertices[0][0] - vertices[1][0], 2) +
Math.pow(vertices[0][1] - vertices[1][1], 2));
dist2 = Math.sqrt(Math.pow(vertices[1][0] - vertices[2][0], 2) +
Math.pow(vertices[1][1] - vertices[2][1], 2));
dist3 = Math.sqrt(Math.pow(vertices[0][0] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2));*/
}
else if(Math.min(vertices[1][0], vertices[2][0]) == vertices[2][0])
{
a = width - (vertices[2][0] - vertices[0][0]);
b = height - (vertices [2][1] - vertices[0][1]);
/*dist1 = Math.sqrt(Math.pow(vertices[0][0] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2));
dist2 = Math.sqrt(Math.pow(vertices[1][0] - vertices[2][0], 2) +
Math.pow(vertices[1][1] - vertices[2][1], 2));
dist3 = Math.sqrt(Math.pow(vertices[0][0] - vertices[1][0], 2) +
Math.pow(vertices[0][1] - vertices[1][1], 2));*/
}
area = (width - 1) * (height - 1) /*- dist1 - dist2 - dist3*/ - (((a - 1)
* (b - 1) /*- dist1*/)/2) - (((width - a - 1) * (height - 1)
/*- dist2*/)/2) - (((width - 1) * (height - b - 1) /*- dist3*/)/2);
}
else if (minX == vertices[1][0])
{
int a = 0,
b = 0;
/*double dist1 = 0,
dist2 = 0,
dist3 = 0;*/
if(Math.min(vertices[0][0], vertices[2][0]) == vertices[0][0])
{
a = width - (vertices[0][0] - vertices[1][0]);
b = height - (vertices [0][1] - vertices[1][1]);
/*dist1 = Math.sqrt(Math.pow(vertices[1][0] - vertices[0][0], 2) +
Math.pow(vertices[1][1] - vertices[0][1], 2));
dist2 = Math.sqrt(Math.pow(vertices[0][0] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2));
dist3 = Math.sqrt(Math.pow(vertices[1][0] - vertices[2][0], 2) +
Math.pow(vertices[1][1] - vertices[2][1], 2));*/
}
else if(Math.min(vertices[0][0], vertices[2][0]) == vertices[2][0])
{
a = width - (vertices[2][0] - vertices[1][0]);
b = height - (vertices [2][1] - vertices[1][1]);
/*dist1 = Math.sqrt(Math.pow(vertices[1][0] - vertices[2][0], 2) +
Math.pow(vertices[1][1] - vertices[2][1], 2));
dist2 = Math.sqrt(Math.pow(vertices[0][0] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2));
dist3 = Math.sqrt(Math.pow(vertices[0][0] - vertices[1][0], 2) +
Math.pow(vertices[0][1] - vertices[1][1], 2));*/
}
area = (width - 1) * (height - 1) /*- dist1 - dist2 - dist3*/ - (((a - 1)
* (b - 1) /*- dist1*/)/2) - (((width - a - 1) * (height - 1)
/*- dist2*/)/2) - (((width - 1) * (height - b - 1) /*- dist3*/)/2);
}
else if (minX == vertices[2][0])
{
int a = 0,
b = 0;
/*double dist1 = 0,
dist2 = 0,
dist3 = 0;*/
if(Math.min(vertices[0][0], vertices[1][0]) == vertices[0][0])
{
a = width - (vertices[0][0] - vertices[2][0]);
b = height - (vertices [0][1] - vertices[2][1]);
/*dist1 = Math.sqrt(Math.pow(vertices[2][0] - vertices[0][0], 2) +
Math.pow(vertices[2][1] - vertices[0][1], 2));
dist2 = Math.sqrt(Math.pow(vertices[0][0] - vertices[1][0], 2) +
Math.pow(vertices[0][1] - vertices[1][1], 2));
dist3 = Math.sqrt(Math.pow(vertices[1][0] - vertices[2][0], 2) +
Math.pow(vertices[1][1] - vertices[2][1], 2));*/
}
else if(Math.min(vertices[0][0], vertices[1][0]) == vertices[1][0])
{
a = width - (vertices[1][0] - vertices[2][0]);
b = height - (vertices [1][1] - vertices[2][1]);
/*dist1 = Math.sqrt(Math.pow(vertices[2][0] - vertices[1][0], 2) +
Math.pow(vertices[2][1] - vertices[1][1], 2));
dist2 = Math.sqrt(Math.pow(vertices[0][0] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2));
dist3 = Math.sqrt(Math.pow(vertices[0][0] - vertices[2][0], 2) +
Math.pow(vertices[0][1] - vertices[2][1], 2));*/
}
area = (width - 1) * (height - 1) /*- dist1 - dist2 - dist3*/ - (((a - 1)
* (b - 1) /*- dist1*/)/2) - (((width - a - 1) * (height - 1)
/*- dist2*/)/2) - (((width - 1) * (height - b - 1) /*- dist3*/)/2);
}
Qualcuno potrebbe aiutarmi a risolvere l'algoritmo oa darmi un modo più semplice/migliore per farlo? Questo codice praticamente non funziona mai.
Mi dispiace per il codice lungo, non sapevo quali parti dovrei aggiungere, quindi ho messo l'intero algoritmo.
Edit: così ho cambiato l'algoritmo a questo (Grazie alla MBo):
public static int answer(int[][] vertices)
{
int a = (Math.abs((vertices[1][0] - vertices[0][0]) * (vertices[2][1]
- vertices[0][1]) - (vertices[2][0] - vertices[0][0]) *
(vertices[1][1] - vertices[0][1])))/2,
b = pointsOnLine(vertices[0][0], vertices[0][1], vertices[1][0],
vertices[1][1]) + pointsOnLine(vertices[1][0],
vertices[1][1], vertices[2][0], vertices[2][1]) +
pointsOnLine(vertices[0][0], vertices[0][1],
vertices[2][0], vertices[2][1]),
area = (2 * a - 2 - b)/2; // Also tried a + (b/2) - 1;
return (int)area;
}
public static int pointsOnLine(int x0, int y0, int x1, int y1)
{
BigInteger b1 = BigInteger.valueOf(Math.abs(x1 - x0)),
b2 = BigInteger.valueOf(Math.abs(y1 - y0));
return b1.gcd(b2).intValue();
}
Ma, non sempre la risposta giusta. Ho fatto qualcosa di male?
E ' nella mia risposta: b = b -3; // perché il vertice era stato contato due volte. –
@ DavidPérezCabrera Ho aggiunto il b-3, ma ottengo ancora risposte sbagliate. – flamespirit919
Potresti darmi i vertici e il risultato atteso? hai provato con il mio algoritmo? –