Use more parallels towards the poles.
This commit is contained in:
parent
01d421d47b
commit
65fb4f748f
4
TODO.txt
4
TODO.txt
@ -1,6 +1,3 @@
|
|||||||
Make parallels denser at the poles where it makes a bigger difference
|
|
||||||
The south pole looks really good with very dense vertices.
|
|
||||||
The parallels should be the circles where the sphere would intersect with a series of concentric, evenly spaced cylinders.
|
|
||||||
Make the panning match the cursor
|
Make the panning match the cursor
|
||||||
Enforce a minimum zoom that will keep the edges of the sphere from showing
|
Enforce a minimum zoom that will keep the edges of the sphere from showing
|
||||||
This probably just needs simple math with the aspect and/or the viewport's diagonal length.
|
This probably just needs simple math with the aspect and/or the viewport's diagonal length.
|
||||||
@ -18,3 +15,4 @@ Add licenses
|
|||||||
Add instructions
|
Add instructions
|
||||||
Fix up code locality
|
Fix up code locality
|
||||||
Give the uniforms simpler names
|
Give the uniforms simpler names
|
||||||
|
Allow setting top and bottom angles in case the photo doesn't reach to the poles
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
(() => {
|
(() => {
|
||||||
const makeSphere = (meridians = 3, parallels = 3) => {
|
const makeSphere = (meridians = 3, bandsPerHemisphere = 1) => {
|
||||||
|
const assert = (cond, msg) => { if (!cond) throw (msg ? msg : "failed assertion"); };
|
||||||
|
|
||||||
// The number of meridians dividing the sphere's surface.
|
// The number of meridians dividing the sphere's surface.
|
||||||
// Two meridians would make an XZ plane.
|
// Two meridians would make an XZ plane.
|
||||||
if (meridians < 3) {
|
assert(meridians >= 3);
|
||||||
throw "meridians must be ≥ 3";
|
assert(Number.isInteger(meridians));
|
||||||
}
|
|
||||||
|
|
||||||
// The number of parallels, including the poles, dividing the sphere's surface.
|
// The number of latitude bands comprising each hemisphere.
|
||||||
// Two parallels would make a vertical line segment.
|
assert(bandsPerHemisphere >= 1);
|
||||||
if (parallels < 3) {
|
assert(Number.isInteger(bandsPerHemisphere));
|
||||||
// throw "parallels must be ≥ 3";
|
|
||||||
}
|
|
||||||
|
|
||||||
const radius = 1;
|
const parallels = bandsPerHemisphere * 2 + 1;
|
||||||
|
|
||||||
// The seam needs two of each vertex so we can map the texture correctly.
|
// The seam needs two of each vertex so we can map the texture correctly.
|
||||||
const vertices = new Float32Array((meridians + 1) * parallels * 5);
|
const vertices = new Float32Array((meridians + 1) * parallels * 5);
|
||||||
@ -21,15 +20,25 @@
|
|||||||
const positionOffset = 0;
|
const positionOffset = 0;
|
||||||
const textureCoordOffset = 3 * vertices.constructor.BYTES_PER_ELEMENT;
|
const textureCoordOffset = 3 * vertices.constructor.BYTES_PER_ELEMENT;
|
||||||
let verticesIdx = 0;
|
let verticesIdx = 0;
|
||||||
|
/*
|
||||||
|
In order to cut down on distortion at the poles, the parallels
|
||||||
|
are not at equal intervals of latitude. Instead, the parallels
|
||||||
|
describe the intersections of the (circum)sphere with a set of
|
||||||
|
concentric, evenly spaced, vertically oriented cylinders. This
|
||||||
|
makes the parallels denser towards the poles, in proportion to
|
||||||
|
how badly that density is needed at any given latitude.
|
||||||
|
*/
|
||||||
for (let p = 0; p < parallels; p++) {
|
for (let p = 0; p < parallels; p++) {
|
||||||
const lat = Math.PI * (p / (parallels - 1) - 0.5);
|
const π = Math.PI;
|
||||||
|
const sin = Math.sin;
|
||||||
|
const lat = π * sin(π * (p - bandsPerHemisphere) / 2 / bandsPerHemisphere) / 2;
|
||||||
const y = Math.sin(lat);
|
const y = Math.sin(lat);
|
||||||
for (let m = 0; m < meridians + 1; m++) {
|
for (let m = 0; m < meridians + 1; m++) {
|
||||||
const long = m * 2 * Math.PI / meridians;
|
const long = m * 2 * Math.PI / meridians;
|
||||||
const x = Math.cos(lat) * Math.sin(long) * radius;
|
const x = Math.cos(lat) * Math.sin(long);
|
||||||
const z = Math.cos(lat) * Math.cos(long) * radius;
|
const z = Math.cos(lat) * Math.cos(long);
|
||||||
const u = m / meridians;
|
const u = m / meridians;
|
||||||
const v = p / (parallels - 1);
|
const v = lat / π + 0.5;
|
||||||
|
|
||||||
vertices[verticesIdx++] = x;
|
vertices[verticesIdx++] = x;
|
||||||
vertices[verticesIdx++] = y;
|
vertices[verticesIdx++] = y;
|
||||||
@ -183,7 +192,6 @@
|
|||||||
const minZoom = 1;
|
const minZoom = 1;
|
||||||
let zoom = 3;
|
let zoom = 3;
|
||||||
viewer.addEventListener("wheel", (evt) => {
|
viewer.addEventListener("wheel", (evt) => {
|
||||||
console.log(evt.deltaY);
|
|
||||||
zoom = Math.max(zoom * (1 - evt.deltaY * 0.005), minZoom);
|
zoom = Math.max(zoom * (1 - evt.deltaY * 0.005), minZoom);
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user