New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

four-js

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

four-js

Render 4 dimensional objects with three.js

latest
Source
npmnpm
Version
2.2.1
Version published
Maintainers
1
Created
Source

four.js

An attemp to render 4 dimensional objects with three.js.

Full demo: anakata

Installation

yarn add four-js
# or
npm --save install four-js

Usage

Full working example here

To run it: git clone https://github.com/paradoxxxzero/four.js && cd four.js && yarn install && yarn start then open http://localhost:44444/examples/tesseract.html

Creating

import { HyperGeometry, shapes } from 'four-js'

// Import tesseract preset shape
const { tesseract } = shapes

// Create an HyperRenderer which will be used to make 4d -> 3d projections
const hyperRenderer = new HyperRenderer(1.5, 5)

4D -> 3D Projection

// Instantiate an HyperMesh with the shape
const hyperMesh = new HyperMesh(shape)

// (...) Setup the three.js scene as usual and add the HyperMesh:
scene.add(hyperMesh)

4D -> 3D Cross Section

// Instantiate an HyperSlice with the shape
const hyperSlice = new HyperSlice(shape)

// (...) Setup the three.js scene as usual and add the HyperSlice:
scene.add(hyperSlice)

Updating

This will render a tesseract that you can then rotate by updating the HyperRenderer rotation:

update() {
  requestAnimationFrame(update)
  // Rotate takes the rotation speed around the 6 planes:
  hyperRenderer.rotate({ xy: 0, xz: 0, xw: 5, yz: 0, yw: 10, zw: 10 })

  // Move the cross section along the w-axis
  hyperRenderer.shiftSlice(0.5, wmin, wmax)

  // Update the hyperMesh
  hyperMesh.update(hyperRenderer)

  // Update the hyperSlice
  hyperSlice.update(hyperRenderer)

  // Render the scene
  renderer.render(scene, camera)
}

Configuration

HyperMesh and HyperSlice accept a configuration object as second argument:

const meshConfig = {
  faces: {
    // Configuration regarding faces
    enabled: true, // Render faces
    useColors: true, // Use vertex coloring through colorGenerator
    colorGenerator: cellColors, // Called with ({shape, colors}) must return a function that returns a colors from ({cell, face, vertex, type}) indexes
    colors: defaultColors, // Colors to chose from
    reuse: 'none', // One of ['all', 'faces', 'none'], specifies whether to duplicate vertex in faces / cells. Useful for polychora due to needing a normal per face per vertex.
    split: 'cells', // One of ['none', 'cells', 'faces'], specifies whether to render one Mesh, one Mesh per cell, one Mesh pes face
    splitScale: 100, // Scale of each split, allow for better comprehension of 4D Mesh when used with split: 'cells'
    material: new MeshPhongMaterial({
      // The material (or list of materials per split) to use when rendering
      transparent: true,
      opacity: 0.25,
      blending: NormalBlending,
      depthWrite: false,
      side: DoubleSide,
      vertexColors: true,
    }),
  },
  edges: {
    // Render edges
    enabled: true,
    useColors: true,
    colorGenerator: cellColors,
    colors: defaultColors,
    reuse: 'faces',
    split: 'cells',
    splitScale: 100,
    material: new LineBasicMaterial({
      transparent: true,
      opacity: 0.25,
      blending: AdditiveBlending,
      depthWrite: false,
      vertexColors: true,
      linewidth: 2,
    }),
  },
  points: {
    // Render points
    enabled: false,
    useColors: true,
    colorGenerator: cellColors,
    colors: defaultColors,
    reuse: 'faces',
    split: 'none',
    splitScale: 100,
    material: new ShaderMaterial({
      uniforms: {
        size: { value: 5 },
        opacity: { value: 0.25 },
      },
      vertexShader: pointsVertexShader,
      fragmentShader: pointsFragmentShader,
      transparent: true,
      blending: AdditiveBlending,
    }),
  },
}

const hyperMesh = new HyperMesh(shape, meshConfig)

// Same configuration (minus split/reuse configs) for HyperSlice:
const sliceConfig = {
  faces: {
    enabled: true,
    useColors: true,
    colorGenerator: cellColors,
    colors: defaultColors,
    material: new MeshPhongMaterial({
      side: DoubleSide,
      shininess: 50,
      vertexColors: true,
    }),
  },
  edges: {
    enabled: true,
    useColors: true,
    colorGenerator: cellColors,
    colors: defaultColors,
    material: new LineBasicMaterial({
      transparent: true,
      opacity: 0.25,
      blending: AdditiveBlending,
      depthWrite: false,
      vertexColors: true,
      linewidth: 2,
    }),
  },
  points: {
    enabled: false,
    useColors: true,
    colorGenerator: cellColors,
    colors: defaultColors,
    material: new ShaderMaterial({
      uniforms: {
        size: { value: 5 },
        opacity: { value: 0.25 },
      },
      vertexShader: pointsVertexShader,
      fragmentShader: pointsFragmentShader,
      transparent: true,
      blending: AdditiveBlending,
    }),
  },
}

const hyperSlice = new HyperSlice(shape, sliceConfig)

Shape definition

The 4 dimensional mesh descriptions are composed of vertices, faces and cells.

Here's what the tesseract description look like:

const tesseract = {
  // These are the classic vertices
  vertices: [
    [1, 1, 1, 1], // 0
    [1, 1, -1, 1], // 1
    [1, -1, -1, 1], // 2
    [1, -1, 1, 1], // 3
    [-1, 1, 1, 1], // 4
    [-1, 1, -1, 1], // 5
    [-1, -1, -1, 1], // 6
    [-1, -1, 1, 1], // 7
    [1, 1, 1, -1], // 8
    [1, 1, -1, -1], // 9
    [1, -1, -1, -1], // 10
    [1, -1, 1, -1], // 11
    [-1, 1, 1, -1], // 12
    [-1, 1, -1, -1], // 13
    [-1, -1, -1, -1], // 14
    [-1, -1, 1, -1], // 15
  ],
  // Each face is made by listing its vertices index
  faces: [
    [0, 1, 2, 3], // 0
    [0, 4, 5, 1], // 1
    [0, 3, 7, 4], // 2
    [3, 2, 6, 7], // 3
    [1, 5, 6, 2], // 4
    [4, 7, 6, 5], // 5
    [0, 1, 9, 8], // 6
    [4, 5, 13, 12], // 7
    [3, 2, 10, 11], // 8
    [7, 6, 14, 15], // 9
    [0, 3, 11, 8], // 10
    [4, 7, 15, 12], // 11
    [1, 2, 10, 9], // 12
    [5, 6, 14, 13], // 13
    [0, 4, 12, 8], // 14
    [1, 5, 13, 9], // 15
    [2, 6, 14, 10], // 16
    [3, 7, 15, 11], // 17
    [11, 10, 9, 8], // 18
    [9, 13, 12, 8], // 19
    [12, 15, 11, 8], // 20
    [15, 14, 10, 11], // 21
    [10, 14, 13, 9], // 22
    [13, 14, 15, 12], // 23
  ],
  // Each cell is made by listing its faces index
  cells: [
    [0, 1, 2, 3, 4, 5], // 0
    [0, 6, 12, 8, 10, 18], // 1
    [1, 6, 14, 7, 15, 19], // 2
    [4, 12, 16, 13, 15, 22], // 3
    [3, 8, 16, 9, 17, 21], // 4
    [2, 10, 17, 11, 14, 20], // 5
    [5, 7, 13, 9, 11, 23], // 6
    [18, 19, 20, 21, 22, 23], // 7
  ],
}

This means that the first cell

    [0, 1, 2, 3, 4, 5], // 0

is composed of 6 faces:

    [0, 1, 2, 3], // 0
    [0, 4, 5, 1], // 1
    [0, 3, 7, 4], // 2
    [3, 2, 6, 7], // 3
    [1, 5, 6, 2], // 4
    [4, 7, 6, 5], // 5

and the first face here

    [0, 1, 2, 3], // 0

is composed of 4 vertices:

    [1, 1, 1, 1], // 0
    [1, 1, -1, 1], // 1
    [1, -1, -1, 1], // 2
    [1, -1, 1, 1], // 3

Following that logic you can try to draw your own 4d models.

Feel free to make pull requests with your own creations!

Contributors

@FranzPoize

For his nice 3-sphere shape which has since been refactored and generalized into uvw-hypersurfaces.

FAQs

Package last updated on 07 Jul 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts