Skip to content

Commit

Permalink
[mod] adjust canvas size properly
Browse files Browse the repository at this point in the history
  • Loading branch information
NaokiHori committed Aug 26, 2024
1 parent 8eaa6bb commit 42e850f
Show file tree
Hide file tree
Showing 15 changed files with 966 additions and 599 deletions.
35 changes: 25 additions & 10 deletions CameraAdjuster/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,27 @@
<title>Camera Adjuster</title>
</head>

<body>
<div id="picture-and-code-container">
<div id="picture-frame">
<canvas id="main-canvas"> Cannot use canvas element </canvas>
<body id="body">
<h1 id="header">Camera Adjuster</h1>

<div id="image-controller">
<div class="textbox-container">
<div>Screen width</div>
<input id="screen-width" type="text" />
</div>
<div class="textbox-container">
<div>Screen height</div>
<input id="screen-height" type="text" />
</div>
<div id="resulting-code"></div>
</div>

<div id="controller-container">
<div id="view-controller">
<div id="elevation" class="slider-container">
<div id="elevation-text"></div>
<input
id="elevation-slider"
class="slider"
type="range"
value="60"
min="-180"
max="179"
step="1"
Expand All @@ -34,7 +39,6 @@
id="azimuth-slider"
class="slider"
type="range"
value="30"
min="-180"
max="179"
step="1"
Expand All @@ -46,7 +50,6 @@
id="zoom-slider"
class="slider"
type="range"
value="1"
min="-2"
max="2"
step="0.1"
Expand All @@ -58,14 +61,26 @@
id="roll-slider"
class="slider"
type="range"
value="0"
min="-180"
max="179"
step="1"
/>
</div>
</div>

<canvas id="main-canvas"> Cannot use canvas element </canvas>

<footer>
<a href="https://github.com/NaokiHori/Contour3D">
&copy; 2024, Naoki Hori
</a>
</footer>

<dialog id="code-modal">
<button id="code-modal-close-button" class="button">Close</button>
<div id="code-space"></div>
</dialog>

<script type="module" src="/src/main.ts"></script>
</body>
</html>
267 changes: 137 additions & 130 deletions CameraAdjuster/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,141 +37,148 @@ const ez: Vector3D = {
z: 1,
};

export interface Config {
screen: {
resolution: {
width: number;
height: number;
};
horizontal: Vector3D;
vertical: Vector3D;
export class Config {
private _elevation: number;
private _azimuth: number;
private _screen: {
width: number;
height: number;
roll: number;
};
camera: {
elevation: number;
azimuth: number;
private _camera: {
zoom: number;
roll: number;
position: Vector3D;
//lookAt: Vector3D;
};
}

function resetConfig(): Config {
return {
screen: {
resolution: {
width: 1440,
height: 1080,
},
horizontal: {
x: 4 / 3,
y: 0,
z: 0,
},
vertical: {
x: 0,
y: 1,
z: 0,
},
},
camera: {
elevation: 60,
azimuth: 30,
zoom: 1,
roll: 0,
position: {
x: 0,
y: 0,
z: 3,
},
},
} satisfies Config;
}
public constructor(
screenWidth: number,
screenHeight: number,
elevation: number,
azimuth: number,
zoom: number,
roll: number,
) {
this._elevation = elevation;
this._azimuth = azimuth;
this._screen = {
width: screenWidth,
height: screenHeight,
roll: roll,
};
this._camera = {
zoom: zoom,
};
}

export let config: Config = resetConfig();

export function updateConfig(
elevation: number,
azimuth: number,
zoom: number,
roll: number,
) {
config = resetConfig();
config.camera.elevation = elevation;
config.camera.azimuth = azimuth;
config.camera.zoom = zoom;
config.camera.roll = roll;
// rotate around (1, 0, 0): elevation
config.screen.horizontal = rodrigues(
ex,
config.camera.elevation,
config.screen.horizontal,
);
config.screen.vertical = rodrigues(
ex,
config.camera.elevation,
config.screen.vertical,
);
config.camera.position = rodrigues(
ex,
config.camera.elevation,
config.camera.position,
);
// rotate around (0, 0, 1): azimuth
config.screen.horizontal = rodrigues(
ez,
config.camera.azimuth,
config.screen.horizontal,
);
config.screen.vertical = rodrigues(
ez,
config.camera.azimuth,
config.screen.vertical,
);
config.camera.position = rodrigues(
ez,
config.camera.azimuth,
config.camera.position,
);
// zoom: move camera and screen synchronously
const norm: number = Math.sqrt(
innerProduct(config.camera.position, config.camera.position),
);
config.camera.position = {
x: (1 + zoom / norm) * config.camera.position.x,
y: (1 + zoom / norm) * config.camera.position.y,
z: (1 + zoom / norm) * config.camera.position.z,
};
// roll: rorate screen with respect to the screen normal
const screenNormal: Vector3D = getScreenNormal(config);
config.screen.horizontal = rodrigues(
screenNormal,
roll,
config.screen.horizontal,
);
config.screen.vertical = rodrigues(
screenNormal,
roll,
config.screen.vertical,
);
}
public get screenWidth(): number {
return this._screen.width;
}

export function getScreenNormal(config: Config): Vector3D {
const cross: Vector3D = crossProduct(
config.screen.horizontal,
config.screen.vertical,
);
return normalize(cross);
}
public set screenWidth(screenWidth: number) {
this._screen.width = screenWidth;
}

export function getScreenCenter(config: Config): Vector3D {
const distance = 1;
const norm: number = Math.sqrt(
innerProduct(config.camera.position, config.camera.position),
);
return {
x: (1 - distance / norm) * config.camera.position.x,
y: (1 - distance / norm) * config.camera.position.y,
z: (1 - distance / norm) * config.camera.position.z,
};
public get screenHeight(): number {
return this._screen.height;
}

public set screenHeight(screenHeight: number) {
this._screen.height = screenHeight;
}

public get screenRoll(): number {
return this._screen.roll;
}

public set screenRoll(screenRoll: number) {
this._screen.roll = screenRoll;
}

public get elevation(): number {
return this._elevation;
}

public set elevation(elevation: number) {
this._elevation = elevation;
}

public get azimuth(): number {
return this._azimuth;
}

public set azimuth(azimuth: number) {
this._azimuth = azimuth;
}

public get cameraZoom(): number {
return this._camera.zoom;
}

public set cameraZoom(cameraZoom: number) {
this._camera.zoom = cameraZoom;
}

public get cameraPosition(): Vector3D {
const elevation: number = this._elevation;
const azimuth: number = this._azimuth;
const zoom: number = this._camera.zoom;
// TODO: hard-coded initial position
let cameraPosition: Vector3D = { x: 0, y: 0, z: 3 };
cameraPosition = rodrigues(ex, elevation, cameraPosition);
cameraPosition = rodrigues(ez, azimuth, cameraPosition);
const norm: number = Math.sqrt(
innerProduct(cameraPosition, cameraPosition),
);
cameraPosition = {
x: (1 + zoom / norm) * cameraPosition.x,
y: (1 + zoom / norm) * cameraPosition.y,
z: (1 + zoom / norm) * cameraPosition.z,
};
return cameraPosition;
}

public get screenVectors(): {
horizontal: Vector3D;
vertical: Vector3D;
normal: Vector3D;
} {
const elevation: number = this._elevation;
const azimuth: number = this._azimuth;
const roll: number = this._screen.roll;
const screenWidth: number = this._screen.width;
const screenHeight: number = this._screen.height;
// initial vectors on xy plane
let screenHorizontal: Vector3D = { x: screenWidth, y: 0, z: 0 };
let screenVertical: Vector3D = { x: 0, y: screenHeight, z: 0 };
// elevation: rotate around ex
screenHorizontal = rodrigues(ex, elevation, screenHorizontal);
screenVertical = rodrigues(ex, elevation, screenVertical);
// azimuth: rotate around ez
screenHorizontal = rodrigues(ez, azimuth, screenHorizontal);
screenVertical = rodrigues(ez, azimuth, screenVertical);
// roll: rorate around screen normal
const screenNormal: Vector3D = normalize(
crossProduct(screenHorizontal, screenVertical),
);
screenHorizontal = rodrigues(screenNormal, roll, screenHorizontal);
screenVertical = rodrigues(screenNormal, roll, screenVertical);
return {
horizontal: screenHorizontal,
vertical: screenVertical,
normal: screenNormal,
};
}

public get screenCenter(): Vector3D {
// TODO: hard-coded screen-camera distance
const distance = 1;
const cameraPosition: Vector3D = this.cameraPosition;
const norm: number = Math.sqrt(
innerProduct(cameraPosition, cameraPosition),
);
return {
x: (1 - distance / norm) * cameraPosition.x,
y: (1 - distance / norm) * cameraPosition.y,
z: (1 - distance / norm) * cameraPosition.z,
};
}
}
Loading

0 comments on commit 42e850f

Please sign in to comment.