Skip to content

Commit

Permalink
Merge pull request #76 from lebesnec/feature/better_rendering
Browse files Browse the repository at this point in the history
Feature/better rendering
  • Loading branch information
lebesnec committed Nov 3, 2023
2 parents ca376a1 + efa3266 commit 2945e7d
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 138 deletions.
20 changes: 13 additions & 7 deletions src/app/scene/scene.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,29 @@

:host ::ng-deep {

.hide-scale .scale, .hide-scale .compass {
display: none;
.hide-scale {
.scale, .compass {
display: none;
}
}

.hide-reticule .reticuleV, .hide-reticule .reticuleH {
display: none;
.hide-reticule {
.reticuleV, .reticuleH {
display: none;
}
}

.hide-labels .label-path, .hide-labels .label, .hide-labels .label-symbol {
display: none;
.hide-labels {
.label-path, .label, .label-symbol {
display: none;
}
}

.hide-orbits .orbit {
display: none;
}

.hide-orbits-satellites .orbit.satellite {
.hide-orbits-satellites .orbit-satellite {
display: none;
}

Expand Down
158 changes: 83 additions & 75 deletions src/app/scene/scene.component.ts

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions src/app/scene/scene.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface Ring {
}

/**
* position: px
* position: km from the Sun
* speed: km/s
* mass: kg
* radius: km
Expand All @@ -59,7 +59,6 @@ export interface CelestialBody {
type: CelestialBodyType;
satellites: CelestialBody[];
orbitBody: CelestialBody | null;
lagrangePoints?: [ LagrangePoint, LagrangePoint, LagrangePoint, LagrangePoint, LagrangePoint ];
rings?: Ring[];
unknownData?: {
speed?: boolean;
Expand All @@ -81,6 +80,14 @@ export enum LagrangePointType {
L5 = 'l5'
}

export const LAGRANGE_POINT_TYPES: LagrangePointType[] = [
LagrangePointType.L1,
LagrangePointType.L2,
LagrangePointType.L3,
LagrangePointType.L4,
LagrangePointType.L5
];

export interface LagrangePoint extends Point {
type: LagrangePointType;
}
Expand Down
68 changes: 31 additions & 37 deletions src/app/scene/scene.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ import * as d3 from 'd3';
import {SOLAR_SYSTEM, SUN} from './data/SolarSystem.data';
import {EARTH} from './data/Earth.data';

/**
* SVG does not work well with big number, so we have to divide each value
* (in km) by this ratio before drawing. SCG also doesn't have much decimal
* precision, so we can't have a ratio too big, or small bodies won't render
* properly. This does NOT take into account the scale applied by the current
* zoom! See https://oreillymedia.github.io/Using_SVG/extras/ch08-precision.html
*/
export const PX_TO_KM = 1e5;

/**
* in km
*/
Expand All @@ -30,47 +21,45 @@ export class SceneService {
body.trueAnomaly = body.meanAnomaly; // TODO
body.position = this.getPositionForTrueAnomaly(body, body.trueAnomaly);
});

EARTH.lagrangePoints = this.getEarthLagrangePoints();
}

/**
* In px, relative to the sun at (0, 0)
*/
public getOrbitEllipse(body: CelestialBody): Ellipse {
public getOrbitEllipse(body: CelestialBody, scale: number): Ellipse {
// convert eccentricity and semi major axis to radius and position using
// https://en.wikipedia.org/wiki/Ellipse#Standard_equation
return {
cx: body.orbitBody.position.x - (body.eccentricity * body.semiMajorAxis / PX_TO_KM),
cy: body.orbitBody.position.y,
rx: body.semiMajorAxis / PX_TO_KM,
ry: Math.sqrt((body.semiMajorAxis ** 2) * (1 - (body.eccentricity ** 2))) / PX_TO_KM
cx: (body.orbitBody.position.x / scale) - ((body.eccentricity * body.semiMajorAxis) / scale),
cy: body.orbitBody.position.y / scale,
rx: body.semiMajorAxis / scale,
ry: Math.sqrt((body.semiMajorAxis ** 2) * (1 - (body.eccentricity ** 2))) / scale
};
}

/**
* Positions in px, relative to the sun at (0, 0)
*/
public getOrbitPath(body: CelestialBody, nbPoints = 360): OrbitPoint[] {
public getOrbitPath(body: CelestialBody, nbPoints: number, scale: number): OrbitPoint[] {
const result = d3.range(0, 360, 360 / nbPoints).map(trueAnomaly => {
const point = this.getPositionForTrueAnomaly(body, trueAnomaly);
return {
trueAnomaly,
x: point.x,
y: point.y
x: point.x / scale,
y: point.y / scale
};
});
// add the body position to the orbit to make sure the orbit path will pass through the body:
result.push({
trueAnomaly: body.trueAnomaly,
x: body.position.x,
y: body.position.y
x: body.position.x / scale,
y: body.position.y / scale
});
return result.sort((p1, p2) => p1.trueAnomaly - p2.trueAnomaly);
}

/**
* in px, relative to the sun at (0, 0)
* in km, relative to the sun at (0, 0)
*/
public getPositionForTrueAnomaly(body: CelestialBody, trueAnomaly): Point {
const d = this.getDistanceToFocusPoint(body, trueAnomaly);
Expand All @@ -83,8 +72,8 @@ export class SceneService {
// we have the position relative to the orbited body, so we add its
// position to have the absolute position (to the sun) of the orbiting body :
return {
x: (xKm / PX_TO_KM) + body.orbitBody.position.x,
y: (yKm / PX_TO_KM) + body.orbitBody.position.y
x: xKm + body.orbitBody.position.x,
y: yKm + body.orbitBody.position.y
};
}

Expand All @@ -99,42 +88,47 @@ export class SceneService {

/**
* https://en.wikipedia.org/wiki/Lagrange_point#Physical_and_mathematical_details
* @returns LagrangePoints the 5 Lagrange points for the earth and sun
* @returns LagrangePoints the 5 Lagrange points for the earth and sun (positions in px from the sun)
*/
private getEarthLagrangePoints(): [ LagrangePoint, LagrangePoint, LagrangePoint, LagrangePoint, LagrangePoint ] {
public getEarthLagrangePoints(scale: number): [ LagrangePoint, LagrangePoint, LagrangePoint, LagrangePoint, LagrangePoint ] {
const earthPos = {
x: EARTH.position.x / scale,
y: EARTH.position.y / scale
};

// Pythagore give the earth-sun distance
const distance = Math.sqrt((EARTH.position.x ** 2) + (EARTH.position.y ** 2));
const distance = Math.sqrt((earthPos.x ** 2) + (earthPos.y ** 2));

// Thales give us l1, l2 and l3 from r and the earth position
let r = distance * Math.cbrt(EARTH.mass / (3 * SUN.mass));
const l1: LagrangePoint = {
x: (EARTH.position.x * (distance - r)) / distance,
y: (EARTH.position.y * (distance - r)) / distance,
x: (earthPos.x * (distance - r)) / distance,
y: (earthPos.y * (distance - r)) / distance,
type: LagrangePointType.L1
};
const l2: LagrangePoint = {
x: (EARTH.position.x * (distance + r)) / distance,
y: (EARTH.position.y * (distance + r)) / distance,
x: (earthPos.x * (distance + r)) / distance,
y: (earthPos.y * (distance + r)) / distance,
type: LagrangePointType.L2
};
r = distance * ((7 * EARTH.mass) / (12 * SUN.mass));
const l3: LagrangePoint = {
x: - (EARTH.position.x * (distance - r)) / distance,
y: - (EARTH.position.y * (distance - r)) / distance,
x: - (earthPos.x * (distance - r)) / distance,
y: - (earthPos.y * (distance - r)) / distance,
type: LagrangePointType.L3
};

// 60° rotation of the earth position give l4
const l4: LagrangePoint = {
x: (EARTH.position.x * Math.cos(60 * DEG_TO_RAD)) + (EARTH.position.y * Math.sin(60 * DEG_TO_RAD)),
y: - (EARTH.position.x * Math.sin(60 * DEG_TO_RAD)) + (EARTH.position.y * Math.cos(60 * DEG_TO_RAD)),
x: (earthPos.x * Math.cos(60 * DEG_TO_RAD)) + (earthPos.y * Math.sin(60 * DEG_TO_RAD)),
y: - (earthPos.x * Math.sin(60 * DEG_TO_RAD)) + (earthPos.y * Math.cos(60 * DEG_TO_RAD)),
type: LagrangePointType.L4
};

// -60° rotation of the earth position give l5
const l5: LagrangePoint = {
x: (EARTH.position.x * Math.cos(-60 * DEG_TO_RAD)) + (EARTH.position.y * Math.sin(-60 * DEG_TO_RAD)),
y: - (EARTH.position.x * Math.sin(-60 * DEG_TO_RAD)) + (EARTH.position.y * Math.cos(-60 * DEG_TO_RAD)),
x: (earthPos.x * Math.cos(-60 * DEG_TO_RAD)) + (earthPos.y * Math.sin(-60 * DEG_TO_RAD)),
y: - (earthPos.x * Math.sin(-60 * DEG_TO_RAD)) + (earthPos.y * Math.cos(-60 * DEG_TO_RAD)),
type: LagrangePointType.L5
};

Expand Down
10 changes: 5 additions & 5 deletions src/app/shell/search-panel/search-panel.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
<img *ngIf="HAS_SYMBOL.includes(body)" [src]="'assets/symbols/' + body.id + '.svg'" [alt]="body.id | translate">
<span class="name">{{ body.id | translate }}</span>
</mat-grid-tile>
<mat-grid-tile *ngFor="let point of searchResultLagrangePoints" class="lagrange-point" (click)="onLagrangePointSelected(point)">
<span class="name">{{ 'Sun–Earth ' + point.type | translate }}</span>
<mat-grid-tile *ngFor="let type of searchResultLagrangePoints" class="lagrange-point" (click)="onLagrangePointSelected(type)">
<span class="name">{{ 'Sun–Earth ' + type | translate }}</span>
</mat-grid-tile>
</mat-grid-list>
</mat-expansion-panel>
Expand Down Expand Up @@ -119,9 +119,9 @@ <h4>
</mat-expansion-panel-header>

<mat-grid-list [cols]="nbCol" gutterSize="10px" rowHeight="50px" class="lagrange-points-grid">
<ng-template ngFor let-point [ngForOf]="EARTH.lagrangePoints">
<mat-grid-tile (click)="onLagrangePointSelected(point)" class="lagrange-point">
<span class="name">{{ 'Sun–Earth ' + point.type | translate }}</span>
<ng-template ngFor let-type [ngForOf]="LAGRANGE_POINT_TYPES">
<mat-grid-tile (click)="onLagrangePointSelected(type)" class="lagrange-point">
<span class="name">{{ 'Sun–Earth ' + type | translate }}</span>
</mat-grid-tile>
</ng-template>
</mat-grid-list>
Expand Down
2 changes: 1 addition & 1 deletion src/app/shell/search-panel/search-panel.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,6 @@ mat-grid-tile.lagrange-point:hover {

// https://github.com/angular/components/issues/11765#issuecomment-937377036
::ng-deep .ng-animating mat-accordion mat-expansion-panel div.mat-expansion-panel-content {
height: 0px;
height: 0;
visibility: hidden;
}
18 changes: 9 additions & 9 deletions src/app/shell/search-panel/search-panel.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import { DWARF_PLANETS } from 'src/app/scene/data/DwarfPlanets.data';
import {HAS_SYMBOL, INNER_PLANETS, OUTER_PLANETS, SOLAR_SYSTEM, SUN} from 'src/app/scene/data/SolarSystem.data';
import {CelestialBody, LAGRANGE_POINT_I18N_KEY, LagrangePoint} from '../../scene/scene.model';
import {CelestialBody, LAGRANGE_POINT_I18N_KEY, LAGRANGE_POINT_TYPES, LagrangePointType} from '../../scene/scene.model';
import {SearchPanelService} from './search-panel.service';
import {GANYMEDE, JUPITER} from '../../scene/data/Jupiter.data';
import {EARTH, MOON} from '../../scene/data/Earth.data';
import {MOON} from '../../scene/data/Earth.data';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import {TranslateService} from '@ngx-translate/core';
Expand All @@ -19,7 +19,7 @@ export class SearchPanelComponent implements OnInit, OnChanges {
@Input() public search = '';

public searchResult: CelestialBody[] | null = null;
public searchResultLagrangePoints: LagrangePoint[] | null = null;
public searchResultLagrangePoints: LagrangePointType[] | null = null;

public get nbCol(): number {
return window.innerWidth <= 600 ? 2 : 4;
Expand All @@ -29,10 +29,10 @@ export class SearchPanelComponent implements OnInit, OnChanges {
public readonly INNER_PLANETS = INNER_PLANETS;
public readonly OUTER_PLANETS = OUTER_PLANETS;
public readonly DWARF_PLANETS = DWARF_PLANETS;
public readonly EARTH = EARTH;
public readonly JUPITER = JUPITER;
public readonly MOON = MOON;
public readonly GANYMEDE = GANYMEDE;
public readonly LAGRANGE_POINT_TYPES = LAGRANGE_POINT_TYPES;
public readonly HAS_SYMBOL = HAS_SYMBOL;
public readonly NB_DWARF_PLANETS_SATELLITES = DWARF_PLANETS.reduce((nb, p) => nb + p.satellites.length, 0);

Expand Down Expand Up @@ -63,8 +63,8 @@ export class SearchPanelComponent implements OnInit, OnChanges {
this.searchService.onBodySelected.next(body);
}

public onLagrangePointSelected(point: LagrangePoint): void {
this.searchService.onLagrangePointSelected.next(point);
public onLagrangePointSelected(type: LagrangePointType): void {
this.searchService.onLagrangePointSelected.next(type);
}

private onSearchChange(): void {
Expand All @@ -73,9 +73,9 @@ export class SearchPanelComponent implements OnInit, OnChanges {
this.searchResult = this.searchService.filter(data, [ 'translation' ], this.search).map(r => r.body);
});

this.translate.get(EARTH.lagrangePoints.map(p => LAGRANGE_POINT_I18N_KEY + p.type)).subscribe(translations => {
const data = EARTH.lagrangePoints.map(point => ({ point, translation: translations[LAGRANGE_POINT_I18N_KEY + point.type] }));
this.searchResultLagrangePoints = this.searchService.filter(data, [ 'translation' ], this.search).map(r => r.point);
this.translate.get(LAGRANGE_POINT_TYPES.map(t => LAGRANGE_POINT_I18N_KEY + t)).subscribe(translations => {
const data = LAGRANGE_POINT_TYPES.map(t => ({ type: t, translation: translations[LAGRANGE_POINT_I18N_KEY + t] }));
this.searchResultLagrangePoints = this.searchService.filter(data, [ 'translation' ], this.search).map(r => r.type);
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/app/shell/search-panel/search-panel.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Injectable } from '@angular/core';
import {Subject} from 'rxjs';
import {CelestialBody, LagrangePoint} from '../../scene/scene.model';
import {CelestialBody, LagrangePointType} from '../../scene/scene.model';

@Injectable({
providedIn: 'root'
})
export class SearchPanelService {

public onBodySelected: Subject<CelestialBody | null> = new Subject();
public onLagrangePointSelected: Subject<LagrangePoint> = new Subject();
public onLagrangePointSelected: Subject<LagrangePointType> = new Subject();

constructor() { }

Expand Down

0 comments on commit 2945e7d

Please sign in to comment.