Skip to content

Commit

Permalink
fix: Tilting the camera angle still displays particles
Browse files Browse the repository at this point in the history
  • Loading branch information
hongfaqiu committed Oct 27, 2024
1 parent 469a9ef commit a0c98a6
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 31 deletions.
7 changes: 7 additions & 0 deletions example/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# example

## 0.3.3

### Patch Changes

- Updated dependencies
- [email protected]

## 0.3.2

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "example",
"private": true,
"version": "0.3.2",
"version": "0.3.3",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
4 changes: 2 additions & 2 deletions example/src/components/ColorTableInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const colorSchemes = [
{ label: 'Purples', value: 'purples', interpolator: interpolatePurples },
].map((item) => ({
...item,
colors: generateColorTable(item.interpolator, item.reverse),
colors: generateColorTable(item.interpolator, true),
}));

const ColorTableInput: React.FC<ColorTableInputProps> = ({
Expand Down Expand Up @@ -91,7 +91,7 @@ const ColorTableInput: React.FC<ColorTableInputProps> = ({
{Array.from({ length: segments }).map((_, i) => (
<ColorSegment
key={i}
color={scheme.interpolator(i / (segments - 1))}
color={scheme.colors[i]}
/>
))}
</ColorPreview>
Expand Down
2 changes: 1 addition & 1 deletion example/src/components/ControlPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ export const ControlPanel: React.FC<ControlPanelProps> = ({
'Factor to adjust the speed of particles. Controls the movement speed of particles.'
)}
>
<Slider min={0.1} max={2} step={0.1} />
<Slider min={0.1} max={10} step={0.1} />
</CompactFormItem>

<CompactFormItem
Expand Down
3 changes: 2 additions & 1 deletion example/src/pages/earth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ const defaultOptions: Partial<WindLayerOptions> = {
dropRateBump: 0.01,
speedFactor: 1.0,
lineWidth: 10.0,
colors: colorSchemes[7].colors,
colors: colorSchemes[2].colors,
flipY: true,
useViewerBounds: true,
};

export function Earth() {
Expand Down
6 changes: 6 additions & 0 deletions packages/cesium-wind-layer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# cesium-wind-layer

## 0.4.3

### Patch Changes

- Tilting the camera angle still displays particles

## 0.4.2

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/cesium-wind-layer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cesium-wind-layer",
"version": "0.4.2",
"version": "0.4.3",
"publishConfig": {
"access": "public"
},
Expand Down
86 changes: 61 additions & 25 deletions packages/cesium-wind-layer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import {
Viewer,
Scene,
Cartesian2,
Cartesian3,
BoundingSphere,
Ellipsoid,
SceneMode,
Math as CesiumMath,
Rectangle
Expand Down Expand Up @@ -166,20 +163,45 @@ export class WindLayer {
}

private updateViewerParameters(): void {
const viewRectangle = this.viewer.camera.computeViewRectangle();
if (viewRectangle) {
let minLon = CesiumMath.toDegrees(Math.max(viewRectangle.west, -Math.PI));
let maxLon = CesiumMath.toDegrees(Math.min(viewRectangle.east, Math.PI));
let minLat = CesiumMath.toDegrees(Math.max(viewRectangle.south, -Math.PI / 2));
let maxLat = CesiumMath.toDegrees(Math.min(viewRectangle.north, Math.PI / 2));
// Add 5% buffer to lonRange and latRange
const lonBuffer = (maxLon - minLon) * 0.05;
const latBuffer = (maxLat - minLat) * 0.05;
minLon = Math.max(this.windData.bounds.west, minLon - lonBuffer);
maxLon = Math.min(this.windData.bounds.east, maxLon + lonBuffer);
minLat = Math.max(this.windData.bounds.south, minLat - latBuffer);
maxLat = Math.min(this.windData.bounds.north, maxLat + latBuffer);
// 计算经纬度范围的交集
const scene = this.viewer.scene;
const canvas = scene.canvas;
const corners = [
{ x: 0, y: 0 },
{ x: 0, y: canvas.clientHeight },
{ x: canvas.clientWidth, y: 0 },
{ x: canvas.clientWidth, y: canvas.clientHeight }
];

// Convert screen corners to cartographic coordinates
let minLon = 180;
let maxLon = -180;
let minLat = 90;
let maxLat = -90;
let isOutsideGlobe = false;

for (const corner of corners) {
const cartesian = scene.camera.pickEllipsoid(
new Cartesian2(corner.x, corner.y),
scene.globe.ellipsoid
);

if (!cartesian) {
isOutsideGlobe = true;
break;
}

const cartographic = scene.globe.ellipsoid.cartesianToCartographic(cartesian);
const lon = CesiumMath.toDegrees(cartographic.longitude);
const lat = CesiumMath.toDegrees(cartographic.latitude);

minLon = Math.min(minLon, lon);
maxLon = Math.max(maxLon, lon);
minLat = Math.min(minLat, lat);
maxLat = Math.max(maxLat, lat);
}

if (!isOutsideGlobe) {
// Calculate intersection with data bounds
const lonRange = new Cartesian2(
Math.max(this.windData.bounds.west, minLon),
Math.min(this.windData.bounds.east, maxLon)
Expand All @@ -189,20 +211,34 @@ export class WindLayer {
Math.min(this.windData.bounds.north, maxLat)
);

// Add 5% buffer to lonRange and latRange
const lonBuffer = (lonRange.y - lonRange.x) * 0.05;
const latBuffer = (latRange.y - latRange.x) * 0.05;

lonRange.x = Math.max(this.windData.bounds.west, lonRange.x - lonBuffer);
lonRange.y = Math.min(this.windData.bounds.east, lonRange.y + lonBuffer);
latRange.x = Math.max(this.windData.bounds.south, latRange.x - latBuffer);
latRange.y = Math.min(this.windData.bounds.north, latRange.y + latBuffer);

this.viewerParameters.lonRange = lonRange;
this.viewerParameters.latRange = latRange;
}

const pixelSize = this.viewer.camera.getPixelSize(
new BoundingSphere(Cartesian3.ZERO, Ellipsoid.WGS84.maximumRadius),
this.viewer.scene.drawingBufferWidth,
this.viewer.scene.drawingBufferHeight
);
// Calculate pixelSize based on the visible range
const dataLonRange = this.windData.bounds.east - this.windData.bounds.west;
const dataLatRange = this.windData.bounds.north - this.windData.bounds.south;

if (pixelSize > 0) {
this.viewerParameters.pixelSize = pixelSize;
// Calculate the ratio of visible area to total data area based on the shortest side
const visibleRatioLon = (lonRange.y - lonRange.x) / dataLonRange;
const visibleRatioLat = (latRange.y - latRange.x) / dataLatRange;
const visibleRatio = Math.min(visibleRatioLon, visibleRatioLat);

// Map the ratio to a pixelSize value between 0 and 1000
const pixelSize = 1000 * visibleRatio;

this.viewerParameters.pixelSize = 5 + Math.max(0, Math.min(1000, pixelSize));
}


this.viewerParameters.sceneMode = this.scene.mode;
this.particleSystem?.applyViewerParameters(this.viewerParameters);
}
Expand Down

0 comments on commit a0c98a6

Please sign in to comment.