test-skybox/createSkyboxImage.js
2024-08-14 16:48:59 +08:00

112 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import hipparcos_catalog from "./hipparcos_7_concise.js";
import CatalogSkybox from "./CatalogSkybox.js";
// 20240814 blitheli
/**
* 由hipparcos星表数据生成天空盒子的一个面的图片
*
* 通过Canvas绘制纯黑色背景行星为白色大小和亮度与星等相关
*
* 用户可以通过这个函数生成天空盒子的6个面的图片然后通过Cesium的SkyBox类创建自定义的天空盒
*
* 目前数据为hipparcos星表数据仅考虑星等7以上亮度./hipparcos_7_concise.js
* 来源: https://github.com/gmiller123456/hip2000
* 可根据需要自行下载和替换数据
*
* @param {number} faceId0 立方体盒子的面id,0: mx, 1: my, 2: px, 3: py, 4: pz, 5: mz
* @param {number} width 图片的宽度(高度也是这个值),单位:像素
* @returns base64格式的图片(png)
*/
function createSkyboxImage(faceId0, width) {
// 恒星亮度(等级),亮度等级越小,亮度越大
const magBright = -1;
const magMedium = 7;
const magDim = 12;
// 恒星大小,单位像素
const sizeBright = 5;
const sizeMedium = 1;
const sizeDim = 0.1;
// 恒星透明度(1为不透明0为透明)
const translucentBright = 1.0;
const translucentMedium = 0.75;
const translucentDim = 0.2;
const d2r = Math.PI / 180;
// 创建width*width的jpg格式的图片背景为黑色随机生成1000个像素点颜色为白色大小从1到5像素不等
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = width;
var context = canvas.getContext("2d");
// 黑色背景
context.fillStyle = "black";
context.fillRect(0, 0, width, width);
// 循环hipparcos数据,hipparcos_catalog为数组
for (var id = 0; id < hipparcos_catalog.length; id++) {
var star = hipparcos_catalog[id];
var mag = star[1];
var ra = star[2];
var dec = star[3];
// 赤经原始为0-360°需要转换为[-180,180]°
if (ra > 180) {
ra = ra - 360;
}
// 赤经赤纬转换为弧度
ra = ra * d2r;
dec = dec * d2r;
// 赤经、赤纬转换为立方盒子坐标,再转换为图片坐标
let { x, y, z } = CatalogSkybox.sphere2CubeXyz(ra, dec);
// 转换为图片坐标i,为横坐标,向右,[0,1]), (j为纵坐标,向下,[0,1])
let { i, j, faceId } = CatalogSkybox.cubeXyzToImgUV(x, y, z);
// 不是当前盒子面的点,不绘制,直接跳过
if (faceId !== faceId0) {
continue;
}
// 像素大小、透明度(根据星等,按照最大值和最小值线性插值)
let size = sizeBright; // 默认最大值
let translucent = translucentBright;
if (mag > magBright && mag <= magMedium) {
size =
sizeMedium +
((sizeBright - sizeMedium) * (mag - magMedium)) /
(magBright - magMedium);
translucent =
translucentMedium +
((translucentBright - translucentMedium) * (mag - magMedium)) /
(magBright - magMedium);
}
// 亮度太暗,设最小值
else if (mag > magMedium) {
size = sizeDim;
translucent = translucentDim;
}
// 图像坐标系下的坐标(考虑到图片的大小,精确到实际的像素坐标)
let u = i * width - size / 2;
let v = j * width - size / 2;
if (u < 0) {
u = 0;
}
if (v < 0) {
v = 0;
}
// 画点,白色,带透明度
context.fillStyle = `rgba(255,255,255,${translucent})`;
context.fillRect(u, v, size, size);
}
// 生成base64格式的图片
var dataUrl = canvas.toDataURL("image/jpeg");
return dataUrl;
}
export default createSkyboxImage;