Skip to content

Commit e5fb68d

Browse files
authored
Use a more robust triangle test (#2037)
fix #2035
1 parent d14bf66 commit e5fb68d

9 files changed

+1089
-8
lines changed

src/marks/raster.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,15 @@ export function interpolatorBarycentric({random = randomLcg(42)} = {}) {
316316
if (x < 0 || x >= width || y < 0 || y >= height) continue;
317317
const xp = x + 0.5; // sample pixel centroids
318318
const yp = y + 0.5;
319-
const ga = ((By - Cy) * (xp - Cx) + (yp - Cy) * (Cx - Bx)) / z;
320-
if (ga < 0) continue;
321-
const gb = ((Cy - Ay) * (xp - Cx) + (yp - Cy) * (Ax - Cx)) / z;
322-
if (gb < 0) continue;
323-
const gc = 1 - ga - gb;
324-
if (gc < 0) continue;
319+
const s = Math.sign(z);
320+
const ga = (By - Cy) * (xp - Cx) + (yp - Cy) * (Cx - Bx);
321+
if (ga * s < 0) continue;
322+
const gb = (Cy - Ay) * (xp - Cx) + (yp - Cy) * (Ax - Cx);
323+
if (gb * s < 0) continue;
324+
const gc = z - (ga + gb);
325+
if (gc * s < 0) continue;
325326
const i = x + width * y;
326-
W[i] = mix(va, ga, vb, gb, vc, gc, x, y);
327+
W[i] = mix(va, ga / z, vb, gb / z, vc, gc / z, x, y);
327328
S[i] = 1;
328329
}
329330
}

test/data/4kpoints.json

Lines changed: 504 additions & 0 deletions
Large diffs are not rendered by default.

test/output/interpolateBarycentric4.svg

Lines changed: 71 additions & 0 deletions
Loading

test/output/interpolateBarycentric4k.svg

Lines changed: 54 additions & 0 deletions
Loading

test/output/rasterPenguinsBarycentric.svg

Lines changed: 1 addition & 1 deletion
Loading

test/output/rasterPenguinsBarycentricBlur.svg

Lines changed: 415 additions & 0 deletions
Loading

test/plots/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ export * from "./industry-unemployment.js";
132132
export * from "./infinity-log.js";
133133
export * from "./integer-interval.js";
134134
export * from "./intern-facet.js";
135+
export * from "./interpolate-barycentric.js";
135136
export * from "./interval-aware.js";
136137
export * from "./intraday-histogram.js";
137138
export * from "./kitten.js";

test/plots/interpolate-barycentric.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import * as Plot from "@observablehq/plot";
2+
3+
export async function interpolateBarycentric4() {
4+
const I = [0, 1, 2, 3];
5+
const X = [297, 295, 80, 59];
6+
const Y = [269, 266, 275, 265];
7+
return Plot.plot({
8+
color: {scheme: "greys", domain: [-0.1, 8]},
9+
x: {domain: [53, 314]},
10+
y: {domain: [265, 276]},
11+
marks: [
12+
Plot.frame({fill: "red"}),
13+
Plot.raster(I, {pixelSize: 1, x: X, y: Y, fill: I, interpolate: "barycentric", imageRendering: "pixelated"}),
14+
Plot.delaunayMesh(I, {x: X, y: Y, stroke: "black"}),
15+
Plot.dot(I, {x: X, y: Y, r: 2, fill: "black"})
16+
]
17+
});
18+
}
19+
20+
export async function interpolateBarycentric4k() {
21+
const {x, y, v} = await fetch("data/4kpoints.json").then((d) => d.json());
22+
return Plot.plot({
23+
color: {scheme: "rdbu", range: [0.2, 0.8]},
24+
x: {domain: [0.5, 580.5]},
25+
y: {domain: [0, 350]},
26+
marks: [
27+
Plot.frame({fill: "black"}),
28+
Plot.raster({length: x.length}, {x, y, fill: v, interpolate: "barycentric", imageRendering: "pixelated"})
29+
]
30+
});
31+
}

test/plots/raster-penguins.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ export async function rasterPenguinsBarycentric() {
1515
return rasterPenguins({interpolate: "barycentric"});
1616
}
1717

18+
export async function rasterPenguinsBarycentricBlur() {
19+
return rasterPenguins({interpolate: "barycentric", blur: 7});
20+
}
21+
1822
export async function rasterPenguinsRandomWalk() {
1923
return rasterPenguins({interpolate: "random-walk"});
2024
}

0 commit comments

Comments
 (0)