Skip to content

【颜色重心插值】

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);

MIT Licensed