Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Viewport and SimulatedRegion position to be the center instead of a corner #675

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project does **not** adhere to [Semantic Versioning](https://semver.org

## [Unreleased]

### Changed

- Viewports and simulated regions now have a minimal size to be resized to. Already placed viewports and simulated regions below this size are not affected.
- Viewports and simulated regions can now not be flipped horizontally or vertically during resizing. Due to not completely accurate migrations, it could be that the positions of such regions in imported exercises are now slightly off.

### Added

- There are now radiograms, which can be used by the simulation to send messages to the trainees
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ export class DragElementService {
const width = height * Viewport.image.aspectRatio;
const viewport = Viewport.create(
{
x: position.x - width / 2,
y: position.y + height / 2,
x: position.x,
y: position.y,
},
{
height,
Expand Down Expand Up @@ -283,8 +283,8 @@ export class DragElementService {
const width = height * SimulatedRegion.image.aspectRatio;
const simulatedRegion = SimulatedRegion.create(
{
x: position.x - width / 2,
y: position.y + height / 2,
x: position.x,
y: position.y,
},
{
height,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ import type VectorSource from 'ol/source/Vector';
import type { Observable } from 'rxjs';
import { Subject } from 'rxjs';
// eslint-disable-next-line @typescript-eslint/no-shadow
import type { Element, UUID } from 'digital-fuesim-manv-shared';
import type { Element, MapCoordinates, UUID } from 'digital-fuesim-manv-shared';
import type { FeatureManager } from '../utility/feature-manager';
import type {
GeometryHelper,
GeometryWithCoordinates,
PositionableElement,
Positions,
} from '../utility/geometry-helper';
import { MovementAnimator } from '../utility/movement-animator';
import type { OlMapInteractionsManager } from '../utility/ol-map-interactions-manager';
Expand All @@ -39,7 +38,7 @@ export abstract class MoveableFeatureManager<
constructor(
protected readonly olMap: OlMap,
private readonly proposeMovementAction: (
newPosition: Positions<FeatureType>,
newPosition: MapCoordinates,
element: ManagedElement
) => void,
protected readonly geometryHelper: GeometryHelper<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ export class SimulatedRegionFeatureManager
) {
super(
olMap,
(targetPositions, simulatedRegion) => {
(targetPosition, simulatedRegion) => {
exerciseService.proposeAction({
type: '[SimulatedRegion] Move simulated region',
simulatedRegionId: simulatedRegion.id,
targetPosition: targetPositions[0]![0]!,
targetPosition,
});
},
new PolygonGeometryHelper()
Expand All @@ -84,7 +84,7 @@ export class SimulatedRegionFeatureManager
const feature = super.createFeature(element);
ResizeRectangleInteraction.onResize(
feature,
({ topLeftCoordinate, scale }) => {
({ centerCoordinate, scale }) => {
const currentElement = this.getElementFromFeature(
feature
) as SimulatedRegion;
Expand All @@ -93,8 +93,8 @@ export class SimulatedRegionFeatureManager
type: '[SimulatedRegion] Resize simulated region',
simulatedRegionId: element.id,
targetPosition: MapCoordinates.create(
topLeftCoordinate[0]!,
topLeftCoordinate[1]!
centerCoordinate[0]!,
centerCoordinate[1]!
),
newSize: Size.create(
currentElement.size.width * scale.x,
Expand Down Expand Up @@ -140,19 +140,16 @@ export class SimulatedRegionFeatureManager
return false;
}
if (
['vehicle', 'personnel', 'material', 'patient'].includes(
droppedElement.type
)
droppedElement.type === 'vehicle' ||
droppedElement.type === 'personnel' ||
droppedElement.type === 'material' ||
droppedElement.type === 'patient'
) {
this.exerciseService.proposeAction(
{
type: '[SimulatedRegion] Add Element',
simulatedRegionId: droppedOnSimulatedRegion.id,
elementToBeAddedType: droppedElement.type as
| 'material'
| 'patient'
| 'personnel'
| 'vehicle',
elementToBeAddedType: droppedElement.type,
Dassderdie marked this conversation as resolved.
Show resolved Hide resolved
elementToBeAddedId: droppedElement.id,
},
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ export class ViewportFeatureManager
) {
super(
olMap,
(targetPositions, viewport) => {
(targetPosition, viewport) => {
exerciseService.proposeAction({
type: '[Viewport] Move viewport',
viewportId: viewport.id,
targetPosition: targetPositions[0]![0]!,
targetPosition,
});
},
new PolygonGeometryHelper()
Expand All @@ -85,7 +85,7 @@ export class ViewportFeatureManager
const feature = super.createFeature(element);
ResizeRectangleInteraction.onResize(
feature,
({ topLeftCoordinate, scale }) => {
({ centerCoordinate, scale }) => {
const currentElement = this.getElementFromFeature(
feature
) as Viewport;
Expand All @@ -94,8 +94,8 @@ export class ViewportFeatureManager
type: '[Viewport] Resize viewport',
viewportId: element.id,
targetPosition: MapCoordinates.create(
topLeftCoordinate[0]!,
topLeftCoordinate[1]!
centerCoordinate[0]!,
centerCoordinate[1]!
),
newSize: Size.create(
currentElement.size.width * scale.x,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,25 @@ export type Coordinates<T extends GeometryWithCoordinates> = Exclude<
null
>;

type ArrayElement<ArrayType> = ArrayType extends readonly (infer ElementType)[]
? ElementType
: never;

type SubstituteCoordinateForPoint<T> = T extends Coordinate
? MapCoordinates
: T extends Array<ArrayElement<T>>
? SubstituteCoordinateForPoint<ArrayElement<T>>[]
: never;

export type Positions<T extends GeometryWithCoordinates> =
SubstituteCoordinateForPoint<Coordinates<T>>;

export interface CoordinatePair<T extends GeometryWithCoordinates> {
startPosition: Coordinates<T>;
endPosition: Coordinates<T>;
}

export interface GeometryHelper<
T extends GeometryWithCoordinates,
GeometryType extends GeometryWithCoordinates,
Element extends PositionableElement = PositionableElement
> {
create: (element: Element) => Feature<T>;
getElementCoordinates: (element: Element) => Coordinates<T>;
getFeatureCoordinates: (feature: Feature<T>) => Coordinates<T>;
create: (element: Element) => Feature<GeometryType>;
getElementCoordinates: (element: Element) => Coordinates<GeometryType>;
getFeatureCoordinates: (
feature: Feature<GeometryType>
) => Coordinates<GeometryType>;
interpolateCoordinates: (
positions: CoordinatePair<T>,
positions: CoordinatePair<GeometryType>,
progress: number
) => Coordinates<T>;
getFeaturePosition: (feature: Feature<T>) => Positions<T>;
) => Coordinates<GeometryType>;
getFeaturePosition: (feature: Feature<GeometryType>) => MapCoordinates;
}

export const interpolate = (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import type { WithPosition } from 'digital-fuesim-manv-shared';
import {
MapCoordinates,
currentCoordinatesOf,
MapCoordinates,
} from 'digital-fuesim-manv-shared';
import { Feature } from 'ol';
import { Point } from 'ol/geom';
import type {
CoordinatePair,
Coordinates,
GeometryHelper,
Positions,
} from './geometry-helper';
import { interpolate } from './geometry-helper';

Expand All @@ -31,7 +30,7 @@ export class PointGeometryHelper implements GeometryHelper<Point> {
): Coordinates<Point> =>
interpolate(positions.startPosition, positions.endPosition, progress);

getFeaturePosition = (feature: Feature<Point>): Positions<Point> =>
getFeaturePosition = (feature: Feature<Point>) =>
MapCoordinates.create(
this.getFeatureCoordinates(feature)[0]!,
this.getFeatureCoordinates(feature)[1]!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import {
MapCoordinates,
} from 'digital-fuesim-manv-shared';
import { Feature } from 'ol';
import { getCenter } from 'ol/extent';
import { Polygon } from 'ol/geom';
import type {
CoordinatePair,
Coordinates,
GeometryHelper,
Positions,
ResizableElement,
} from './geometry-helper';
import { interpolate } from './geometry-helper';
Expand All @@ -21,24 +21,24 @@ export class PolygonGeometryHelper

getElementCoordinates = (
element: ResizableElement
): Coordinates<Polygon> => [
[
[currentCoordinatesOf(element).x, currentCoordinatesOf(element).y],
): Coordinates<Polygon> => {
const center = currentCoordinatesOf(element);
const { width, height } = element.size;
return [
[
currentCoordinatesOf(element).x + element.size.width,
currentCoordinatesOf(element).y,
// top left
[center.x - width / 2, center.y + height / 2],
// top right
[center.x + width / 2, center.y + height / 2],
// bottom right
[center.x + width / 2, center.y - height / 2],
// bottom left
[center.x - width / 2, center.y - height / 2],
// top left (close the rectangle)
[center.x - width / 2, center.y + height / 2],
],
[
currentCoordinatesOf(element).x + element.size.width,
currentCoordinatesOf(element).y - element.size.height,
],
[
currentCoordinatesOf(element).x,
currentCoordinatesOf(element).y - element.size.height,
],
[currentCoordinatesOf(element).x, currentCoordinatesOf(element).y],
],
];
];
};

getFeatureCoordinates = (feature: Feature<Polygon>): Coordinates<Polygon> =>
feature.getGeometry()!.getCoordinates();
Expand All @@ -57,10 +57,11 @@ export class PolygonGeometryHelper
)
);

getFeaturePosition = (feature: Feature<Polygon>): Positions<Polygon> =>
this.getFeatureCoordinates(feature).map((coordinates) =>
coordinates.map((coordinate) =>
MapCoordinates.create(coordinate[0]!, coordinate[1]!)
)
getFeaturePosition = (feature: Feature<Polygon>) => {
const centerCoordinates = getCenter(feature.getGeometry()!.getExtent());
return MapCoordinates.create(
centerCoordinates[0]!,
centerCoordinates[1]!
);
};
}
Loading