2021-06-15 00:49:18 -07:00
---
id: 5a23c84252665b21eecc8045
2021-09-07 07:47:37 -07:00
title: Recorte de polígonos de Sutherland-Hodgman
2021-06-15 00:49:18 -07:00
challengeType: 5
forumTopicId: 302336
dashedName: sutherland-hodgman-polygon-clipping
---
# --description--
2021-09-07 07:47:37 -07:00
O [algoritmo de recorte de polígonos de Sutherland-Hodgman ](https://en.wikipedia.org/wiki/Sutherland-Hodgman clipping algorithm ) encontra o polígono que é a intersecção entre um polígono arbitrário (o "polígono sujeito") e um polígono convexo (o "polígono de recorte"). Ele é usado em gráficos de computador (especialmente gráficos 2D) para reduzir a complexidade de uma cena que está sendo exibida eliminando partes de um polígono que não precisam ser exibidas. Pegue o polígono que se fecha definido pelos pontos:
2021-06-15 00:49:18 -07:00
< pre > [(50, 150), (200, 50), (350, 150), (350, 300), (250, 300), (200, 250), (150, 350), (100, 250), (100, 200)]< / pre >
2021-09-07 07:47:37 -07:00
e recorte-o pelo retângulo definido pelos pontos:
2021-06-15 00:49:18 -07:00
< pre > [(100, 100), (300, 100), (300, 300), (100, 300)]< / pre >
# --instructions--
2021-09-07 07:47:37 -07:00
Escreva uma função que receba dois arrays como parâmetro. O primeiro array contém os pontos do polígono sujeito e o segundo array contém os pontos do polígono de recorte. A função deve retornar um array contendo os pontos do polígono recortado. Cada número deve ser arredondado para 3 casas decimais.
2021-06-15 00:49:18 -07:00
# --hints--
2021-09-07 07:47:37 -07:00
`clip` deve ser uma função.
2021-06-15 00:49:18 -07:00
```js
assert(typeof clip == 'function');
```
2021-09-07 07:47:37 -07:00
`clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]])` deve retornar um array.
2021-06-15 00:49:18 -07:00
```js
assert(
Array.isArray(
clip(
[
[50, 150],
[200, 50],
[350, 150],
[350, 300],
[250, 300],
[200, 250],
[150, 350],
[100, 250],
[100, 200]
],
[
[100, 100],
[300, 100],
[300, 300],
[100, 300]
]
)
)
);
```
2021-09-07 07:47:37 -07:00
`clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]])` deve retornar `[[100, 116.667], [125, 100], [275, 100], [300, 116.667], [300, 300], [250, 300], [200, 250], [175, 300], [125, 300], [100, 250]]` .
2021-06-15 00:49:18 -07:00
```js
assert.deepEqual(
clip(
[
[50, 150],
[200, 50],
[350, 150],
[350, 300],
[250, 300],
[200, 250],
[150, 350],
[100, 250],
[100, 200]
],
[
[100, 100],
[300, 100],
[300, 300],
[100, 300]
]
),
[
[100, 116.667],
[125, 100],
[275, 100],
[300, 116.667],
[300, 300],
[250, 300],
[200, 250],
[175, 300],
[125, 300],
[100, 250]
]
);
```
2021-09-07 07:47:37 -07:00
`clip([[150, 200], [400, 450], [30, 50]], [[10, 10], [300, 200], [400, 600], [100, 300]])` deve retornar `[[150, 200], [350, 400], [348.611, 394.444], [30, 50]]` .
2021-06-15 00:49:18 -07:00
```js
assert.deepEqual(
clip(
[
[150, 200],
[400, 450],
[30, 50]
],
[
[10, 10],
[300, 200],
[400, 600],
[100, 300]
]
),
[
[150, 200],
[350, 400],
[348.611, 394.444],
[30, 50]
]
);
```
2021-09-07 07:47:37 -07:00
`clip([[250, 200], [100, 450], [130, 250]], [[50, 60], [100, 230], [400, 600], [100, 300]])` deve retornar `[[129.167, 329.167], [119.565, 319.565], [121.854, 304.305]]` .
2021-06-15 00:49:18 -07:00
```js
assert.deepEqual(
clip(
[
[250, 200],
[100, 450],
[130, 250]
],
[
[50, 60],
[100, 230],
[400, 600],
[100, 300]
]
),
[
[129.167, 329.167],
[119.565, 319.565],
[121.854, 304.305]
]
);
```
# --seed--
## --seed-contents--
```js
function clip(subjectPolygon, clipPolygon) {
}
```
# --solutions--
```js
function clip(subjectPolygon, clipPolygon) {
var cp1, cp2, s, e, i, j;
var inside = function(p) {
return (
(cp2[0] - cp1[0]) * (p[1] - cp1[1]) > (cp2[1] - cp1[1]) * (p[0] - cp1[0])
);
};
var intersection = function() {
var dc = [cp1[0] - cp2[0], cp1[1] - cp2[1]],
dp = [s[0] - e[0], s[1] - e[1]],
n1 = cp1[0] * cp2[1] - cp1[1] * cp2[0],
n2 = s[0] * e[1] - s[1] * e[0],
n3 = 1.0 / (dc[0] * dp[1] - dc[1] * dp[0]);
return [(n1 * dp[0] - n2 * dc[0]) * n3, (n1 * dp[1] - n2 * dc[1]) * n3];
};
var outputList = subjectPolygon;
cp1 = clipPolygon[clipPolygon.length - 1];
for (j in clipPolygon) {
var cp2 = clipPolygon[j];
var inputList = outputList;
outputList = [];
s = inputList[inputList.length - 1]; //last on the input list
for (i in inputList) {
var e = inputList[i];
if (inside(e)) {
if (!inside(s)) {
outputList.push(intersection());
}
outputList.push(e);
} else if (inside(s)) {
outputList.push(intersection());
}
s = e;
}
cp1 = cp2;
}
return outputList.map(e => e.map(f => Math.round(f * 1000) / 1000));
}
```