Appearance
【颜色重心插值】
js
/**
* 计算三角形的重心坐标
* @param {number} x - 目标点x坐标
* @param {number} y - 目标点y坐标
* @param {number} x1 - 三角形顶点1的x坐标
* @param {number} y1 - 三角形顶点1的y坐标
* @param {number} x2 - 三角形顶点2的x坐标
* @param {number} y2 - 三角形顶点2的y坐标
* @param {number} x3 - 三角形顶点3的x坐标
* @param {number} y3 - 三角形顶点3的y坐标
* @returns {Object} 重心坐标 {alpha, beta, gamma}
*/
function calculateBarycentricCoordinates(x, y, x1, y1, x2, y2, x3, y3) {
// 计算三角形面积
const area = 0.5 * (-y2 * x3 + y1 * (-x2 + x3) + x1 * (y2 - y3) + x2 * y3);
// 计算子三角形面积
const area1 = 0.5 * (-y2 * x3 + y * (-x2 + x3) + x * (y2 - y3) + x2 * y3);
const area2 = 0.5 * (-y * x3 + y1 * (-x + x3) + x1 * (y - y3) + x * y3);
const area3 = 0.5 * (-y2 * x + y1 * (-x2 + x) + x1 * (y2 - y) + x2 * y);
// 计算重心坐标
const alpha = area1 / area;
const beta = area2 / area;
const gamma = area3 / area;
return { alpha, beta, gamma };
}
/**
* 颜色重心插值函数
* @param {Object} point - 目标点坐标 {x, y}
* @param {Array} triangle - 三角形顶点数组 [{x, y, color}, ...]
* @returns {string} 插值后的颜色值(十六进制格式)
*/
function barycentricColorInterpolation(point, triangle) {
// 获取三角形顶点坐标和颜色
const [v1, v2, v3] = triangle;
// 计算重心坐标
const { alpha, beta, gamma } = calculateBarycentricCoordinates(
point.x, point.y,
v1.x, v1.y,
v2.x, v2.y,
v3.x, v3.y
);
// 将十六进制颜色转换为RGB
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
// 将RGB转换为十六进制
function rgbToHex(r, g, b) {
return '#' + [r, g, b].map(x => {
const hex = Math.round(x).toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join('');
}
// 获取三个顶点的RGB颜色
const color1 = hexToRgb(v1.color);
const color2 = hexToRgb(v2.color);
const color3 = hexToRgb(v3.color);
// 计算插值后的RGB值
const r = alpha * color1.r + beta * color2.r + gamma * color3.r;
const g = alpha * color1.g + beta * color2.g + gamma * color3.g;
const b = alpha * color1.b + beta * color2.b + gamma * color3.b;
// 返回十六进制颜色值
return rgbToHex(r, g, b);
}
// 使用示例
const triangle = [
{ x: 0, y: 0, color: '#FF0000' }, // 红色顶点
{ x: 100, y: 0, color: '#00FF00' }, // 绿色顶点
{ x: 50, y: 100, color: '#0000FF' } // 蓝色顶点
];
const point = { x: 50, y: 50 };
const interpolatedColor = barycentricColorInterpolation(point, triangle);
console.log('插值后的颜色:', interpolatedColor);