clip method
bool
clip(
- double x1,
- double y1,
- double x2,
- double y2,
- double x3,
- double y3,
- Float32List clippingArea,
- Float32List output,
Implementation
bool clip(double x1, double y1, double x2, double y2, double x3, double y3,
Float32List clippingArea, Float32List output) {
final Float32List originalOutput = output;
bool clipped = false;
// Avoid copy at the end.
Float32List input;
if (clippingArea.length % 4 >= 2) {
input = output;
output = scratch as Float32List;
} else {
input = scratch as Float32List;
}
input
..length = 0
..add(x1)
..add(y1)
..add(x2)
..add(y2)
..add(x3)
..add(y3)
..add(x1)
..add(y1);
output.length = 0;
final Float32List clippingVertices = clippingArea;
final int clippingVerticesLast = clippingArea.length - 4;
for (int i = 0;; i += 2) {
final double edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
final double edgeX2 = clippingVertices[i + 2],
edgeY2 = clippingVertices[i + 3];
final double deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
final Float32List inputVertices = input;
final int inputVerticesLength = input.length - 2,
outputStart = output.length;
for (int ii = 0; ii < inputVerticesLength; ii += 2) {
final double inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
final double inputX2 = inputVertices[ii + 2],
inputY2 = inputVertices[ii + 3];
final bool side2 =
deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
if (side2) {
// v1 inside, v2 inside
output
..add(inputX2)
..add(inputY2);
continue;
}
// v1 inside, v2 outside
final double c0 = inputY2 - inputY, c2 = inputX2 - inputX;
final double ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) /
(c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
output
..add(edgeX + (edgeX2 - edgeX) * ua)
..add(edgeY + (edgeY2 - edgeY) * ua);
} else if (side2) {
// v1 outside, v2 inside
final double c0 = inputY2 - inputY, c2 = inputX2 - inputX;
final double ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) /
(c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
output
..add(edgeX + (edgeX2 - edgeX) * ua)
..add(edgeY + (edgeY2 - edgeY) * ua)
..add(inputX2)
..add(inputY2);
}
clipped = true;
}
if (outputStart == output.length) {
// All edges outside.
originalOutput.length = 0;
return true;
}
output
..add(output[0])
..add(output[1]);
if (i == clippingVerticesLast) break;
final Float32List temp = output;
output = input..length = 0;
input = temp;
}
if (originalOutput != output) {
originalOutput.length = 0;
final int n = output.length - 2;
for (int i = 0; i < n; i++) {
originalOutput[i] = output[i];
}
} else {
originalOutput.length = originalOutput.length - 2;
}
return clipped;
}