Table of Contents

Struct Camera2

Namespace
Thunder.UnitsNET.Vectors.MonoGame
Assembly
Thunder.UnitsNET.Vectors.MonoGame.dll

An immutable 2D camera that converts between world-space LengthPoint2 positions and screen-space Microsoft.Xna.Framework.Vector2 pixel coordinates.

public readonly record struct Camera2 : IEquatable<Camera2>
Implements
Inherited Members

Remarks

Camera2 is a readonly record struct. All "mutating" operations (such as ZoomBy(double)) return a new instance. Late-bound camera state (e.g. a camera field that is not set in a constructor) will be default, not null — guard against Position being Origin and Scale being zero if the camera may not yet be initialised.

The camera is centred on Position in world space. The centre of the screen always displays the camera's world position. Points to the right of the camera appear to the right on screen; points above the camera appear higher on screen (subject to the YAxis convention).

The Scale defines the zoom level: more pixels per world unit means the world appears larger on screen (zoomed in). Use ZoomBy(double) to adjust zoom and Lerp(PixelScale, PixelScale, double) to animate it smoothly.

Camera2 is stateless: it holds no mutable fields and carries no render state. Create one per frame (or whenever the camera moves) and pass it to your render system. For high-frequency render loops, compute screenSize once per frame and store it as a local variable rather than recalculating it on every WorldToScreen(LengthPoint2, Vector2) call.

// Define the camera: centred on the player, 32 pixels per metre, Y-down (MonoGame default).
var camera = new Camera2(
    Position: player.Position,
    Scale: PixelScale.PerMeter(32));

// In the render loop: Vector2 screenPos = camera.WorldToScreen(enemy.Position, screenSize); spriteBatch.Draw(enemyTexture, screenPos, Color.White);

// Smooth zoom in an update loop: _currentScale = PixelScale.Lerp(_currentScale, _targetScale, deltaTime * smoothSpeed); camera = camera with { Scale = _currentScale };

Constructors

Camera2(LengthPoint2, PixelScale, YAxisMode)

An immutable 2D camera that converts between world-space LengthPoint2 positions and screen-space Microsoft.Xna.Framework.Vector2 pixel coordinates.

public Camera2(LengthPoint2 Position, PixelScale Scale, YAxisMode YAxis = YAxisMode.YDown)

Parameters

Position LengthPoint2

The world-space point that maps to the centre of the screen.

Scale PixelScale

The zoom level expressed as a PixelScale. For example, PixelScale.PerMeter(32) means one metre occupies 32 pixels.

YAxis YAxisMode

Whether the screen Y axis increases downward (YDown, the MonoGame default) or upward (YUp). Defaults to YDown.

Remarks

Camera2 is a readonly record struct. All "mutating" operations (such as ZoomBy(double)) return a new instance. Late-bound camera state (e.g. a camera field that is not set in a constructor) will be default, not null — guard against Position being Origin and Scale being zero if the camera may not yet be initialised.

The camera is centred on Position in world space. The centre of the screen always displays the camera's world position. Points to the right of the camera appear to the right on screen; points above the camera appear higher on screen (subject to the YAxis convention).

The Scale defines the zoom level: more pixels per world unit means the world appears larger on screen (zoomed in). Use ZoomBy(double) to adjust zoom and Lerp(PixelScale, PixelScale, double) to animate it smoothly.

Camera2 is stateless: it holds no mutable fields and carries no render state. Create one per frame (or whenever the camera moves) and pass it to your render system. For high-frequency render loops, compute screenSize once per frame and store it as a local variable rather than recalculating it on every WorldToScreen(LengthPoint2, Vector2) call.

// Define the camera: centred on the player, 32 pixels per metre, Y-down (MonoGame default).
var camera = new Camera2(
    Position: player.Position,
    Scale: PixelScale.PerMeter(32));

// In the render loop: Vector2 screenPos = camera.WorldToScreen(enemy.Position, screenSize); spriteBatch.Draw(enemyTexture, screenPos, Color.White);

// Smooth zoom in an update loop: _currentScale = PixelScale.Lerp(_currentScale, _targetScale, deltaTime * smoothSpeed); camera = camera with { Scale = _currentScale };

Properties

Position

The world-space point that maps to the centre of the screen.

public LengthPoint2 Position { get; init; }

Property Value

LengthPoint2

Scale

The zoom level expressed as a PixelScale. For example, PixelScale.PerMeter(32) means one metre occupies 32 pixels.

public PixelScale Scale { get; init; }

Property Value

PixelScale

YAxis

Whether the screen Y axis increases downward (YDown, the MonoGame default) or upward (YUp). Defaults to YDown.

public YAxisMode YAxis { get; init; }

Property Value

YAxisMode

Methods

ScreenToWorld(Vector2, Vector2)

Converts a screen-space pixel coordinate back to a world-space position.

public LengthPoint2 ScreenToWorld(Vector2 screenPoint, Vector2 screenSize)

Parameters

screenPoint Vector2

The pixel coordinate on the screen.

screenSize Vector2

The size of the render target in pixels (width, height). Must match the value passed to WorldToScreen(LengthPoint2, Vector2) to get an exact inverse.

Returns

LengthPoint2

The world-space LengthPoint2 corresponding to the screen pixel, expressed in Unit.

Examples

LengthPoint2 worldMouse = camera.ScreenToWorld(mouseState.Position.ToVector2(), screenSize);
bool hit = circle.Contains(worldMouse);

Remarks

This is the exact inverse of WorldToScreen(LengthPoint2, Vector2): ScreenToWorld(WorldToScreen(p, size), size) ≈ p within floating-point precision. Typical use is mouse picking — convert the cursor's screen position to a world coordinate to test against game objects.

WorldToScreen(LengthPoint2, Vector2)

Converts a world-space position to a screen-space pixel coordinate.

public Vector2 WorldToScreen(LengthPoint2 worldPoint, Vector2 screenSize)

Parameters

worldPoint LengthPoint2

The position in world space to project.

screenSize Vector2

The size of the render target in pixels (width, height). The screen centre is at screenSize / 2.

Returns

Vector2

The pixel coordinate on screen. The screen centre corresponds to Position. Values outside [0, screenSize] are off-screen but valid — callers may clip as needed.

Examples

var camera = new Camera2(LengthPoint2.Origin, PixelScale.PerMeter(32));
Vector2 px = camera.WorldToScreen(entity.Position, new Vector2(1920, 1080));

WorldToScreenScale(Length)

Converts a world-space length (such as a shape radius) to a pixel size for rendering.

public float WorldToScreenScale(Length worldLength)

Parameters

worldLength Length

The length in world space to convert.

Returns

float

The equivalent size in pixels as a float. Lengths in units other than Unit are automatically converted.

Examples

Single pixelRadius = camera.WorldToScreenScale(circle.Radius);
// Draw a circle at the projected centre with pixelRadius

Remarks

Use this when you need a scalar pixel size rather than a position — for example, to compute the pixel radius of a Circle2 for drawing. Y-axis mode does not affect this result; lengths are always positive.

ZoomBy(double)

Returns a new Camera2 with the zoom level multiplied by factor. Position and YAxis are unchanged.

public Camera2 ZoomBy(double factor)

Parameters

factor double

The zoom multiplier. Values greater than 1.0 zoom in (more pixels per unit); values between 0 and 1.0 zoom out (fewer pixels per unit).

Returns

Camera2

A new Camera2 with the adjusted Scale.

Examples

// Zoom in 10% each frame while a button is held
if (zoomInHeld)
    camera = camera.ZoomBy(1.1);

ZoomBy(double, Vector2, Vector2)

Returns a new Camera2 zoomed by factor, adjusted so that screenFocus remains at the same world position before and after the zoom.

public Camera2 ZoomBy(double factor, Vector2 screenFocus, Vector2 screenSize)

Parameters

factor double

The zoom multiplier. Values greater than 1.0 zoom in; values between 0 and 1.0 zoom out. Must be positive and non-zero.

screenFocus Vector2

The screen-space pixel coordinate that should stay fixed during the zoom — typically the cursor position or the centre of a pinch gesture.

screenSize Vector2

The size of the render target in pixels (width, height). For high-frequency render loops, compute this once per frame and pass it in rather than recalculating it on every call.

Returns

Camera2

A new Camera2 whose Scale has been multiplied by factor and whose Position has been adjusted so that the world point under screenFocus is unchanged.

Examples

// Zoom in 2× toward the cursor position
camera = camera.ZoomBy(2.0, mouseState.Position.ToVector2(), screenSize);

Remarks

The adjustment formula is: newPosition = worldFocus + (oldPosition − worldFocus) / factor, where worldFocus = ScreenToWorld(screenFocus, screenSize) on the pre-zoom camera.

factor is a raw double multiplier rather than a Ratio because it represents a scale change, not a fractional quantity.

v0.5.0 ▼