Code Monkey home page Code Monkey logo

vector's Introduction

Vector

Coverage Go Report Card GoDoc

Collection of generic, immutable vector math functions I've written overtime for different hobby projects.

API

Function Vector2 Vector3 Vector4 Description
Abs Returns a vector with each component's absolute value
Add Component Wise Addition
Angle Returns the angle between two vectors
Ceil Ceils each vectors component to the nearest integer
Clamp Clamps each component between two values
ContainsNaN Returns true if any component of the vector is NaN
Cross Returns the cross product between two vectors
Dot Returns the dot product between two vectors
Flip Scales the vector by -1
FlipX Returns a vector with the X component multiplied by -1
FlipY Returns a vector with the Y component multiplied by -1
FlipZ Returns a vector with the Z component multiplied by -1
FlipW Returns a vector with the W component multiplied by -1
Floor Floors each vectors component
Format Build a string with vector data
Length Returns the length of the vector
LengthSquared Returns the squared length of the vector
Max Returns a new vector where each component is the largest value between the two vectors
MaxX Returns the largest X component between the two vectors
MaxY Returns the largest Y component between the two vectors
MaxZ Returns the largest Z component between the two vectors
MaxW Returns the largest W component between the two vectors
MaxComponent Returns the vectors largest component
Midpoint Finds the mid point between two vectors
Min Returns a new vector where each component is the smallest value between the two vectors
MinX Returns the smallest X component between the two vectors
MinY Returns the smallest Y component between the two vectors
MinZ Returns the smallest Z component between the two vectors
MinW Returns the smallest W component between the two vectors
MinComponent Returns the vectors smallest component
Normalized Returns the normalized vector
NearZero Returns true if all of the components are near 0
Round Rounds each vectors component to the nearest integer
Scale Scales the vector by some constant
Sqrt Returns a vector with each component's square root
Sub Component Wise Subtraction
Values Returns all components of the vector
X Returns the x component of the vector
Y Returns the y component of the vector
Z Returns the z component of the vector
W Returns the w component of the vector
XY Equivalent to vector2.New[T](v.x, v.y)
YZ Equivalent to vector2.New[T](v.y, v.z)
XZ Equivalent to vector2.New[T](v.x, v.z)
YX Equivalent to vector2.New[T](v.y, v.x)
ZX Equivalent to vector2.New[T](v.z, v.x)
ZY Equivalent to vector2.New[T](v.z, v.y)
Log Returns the natural logarithm for each component
Log2 Returns the binary logarithm for each component
Log10 Returns the decimal logarithm for each component
Exp Returns e**x, the base-e exponential for each component
Exp2 Returns 2**x, the base-2 exponential for each component
Expm1 Returns e**x - 1, the base-e exponential for each component minus 1. It is more accurate than Exp(x) - 1 when the component is near zero
Write Write vector component data as binary to io.Writer

Example

Below is an example on how to implement the different sign distance field functions in a generic fashion to work for both int8, int16, int32 int, int64, float32, and float64.

The code below produces this output:

out.gif

package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math"
	"os"

	"github.com/EliCDavis/vector"
	"github.com/EliCDavis/vector/vector2"
	"github.com/EliCDavis/vector/vector3"
)

type Field[T vector.Number] func(v vector3.Vector[T]) float64

func Sphere[T vector.Number](pos vector3.Vector[T], radius float64) Field[T] {
	return func(v vector3.Vector[T]) float64 {
		return v.Distance(pos) - radius
	}
}

func Box[T vector.Number](pos vector3.Vector[T], bounds vector3.Vector[T]) Field[T] {
	halfBounds := bounds.Scale(0.5)
	// It's best to watch the video to understand
	// https://www.youtube.com/watch?v=62-pRVZuS5c
	return func(v vector3.Vector[T]) float64 {
		q := v.Sub(pos).Abs().Sub(halfBounds)
		inside := math.Min(float64(q.MaxComponent()), 0)
		return vector3.Max(q, vector3.Zero[T]()).Length() + inside
	}
}

func Union[T vector.Number](fields ...Field[T]) Field[T] {
	return func(v vector3.Vector[T]) float64 {
		min := math.MaxFloat64

		for _, f := range fields {
			fv := f(v)
			if fv < min {
				min = fv
			}
		}

		return min
	}
}

func Intersect[T vector.Number](fields ...Field[T]) Field[T] {
	return func(v vector3.Vector[T]) float64 {
		max := -math.MaxFloat64

		for _, f := range fields {
			fv := f(v)
			if fv > max {
				max = fv
			}
		}

		return max
	}
}

func Subtract[T vector.Number](minuend, subtrahend Field[T]) Field[T] {
	return func(f vector3.Vector[T]) float64 {
		return math.Max(minuend(f), -subtrahend(f))
	}
}

func Translate[T vector.Number](field Field[T], translation vector3.Vector[T]) Field[T] {
	return func(v vector3.Vector[T]) float64 {
		return field(v.Sub(translation))
	}
}

func evaluateAtDepth[T vector.Number](dimension int, field Field[T], depth T, i int) {
	img := image.NewRGBA(image.Rectangle{
		image.Point{0, 0},
		image.Point{dimension, dimension},
	})

	for x := 0; x < dimension; x++ {
		for y := 0; y < dimension; y++ {
			v := field(vector3.New[T](T(x), T(y), depth))
			byteVal := (v / float64(dimension/20)) * 255
			var c color.Color
			if v > 0 {
				c = color.RGBA{R: 0, G: 0, B: byte(byteVal), A: 255}
			} else {
				c = color.RGBA{R: 0, G: byte(-byteVal), B: 0, A: 255}
			}
			img.Set(x, y, c)
		}
	}

	f, err := os.Create(fmt.Sprintf("field_%04d.png", i))
	if err != nil {
		panic(err)
	}
	defer f.Close()

	err = png.Encode(f, img)
	if err != nil {
		panic(err)
	}
}

func main() {
	dimension := 512
	quarterDim := float64(dimension) / 4.

	middleCoord := vector2.
		Fill(dimension).
		Scale(0.5).
		ToFloat64()

	middleCord3D := vector3.New(middleCoord.X(), middleCoord.Y(), 0)

	smallRing := Subtract(
		Sphere(middleCord3D, 100),
		Sphere(middleCord3D, 50),
	)

	field := Intersect(
		Subtract(
			Sphere(middleCord3D, 200),
			Sphere(middleCord3D, 100),
		),
		Union(
			Translate(smallRing, vector3.New(1., 1., 0.).Scale(quarterDim)),
			Translate(smallRing, vector3.New(1., -1., 0.).Scale(quarterDim)),
			Translate(smallRing, vector3.New(-1., 1., 0.).Scale(quarterDim)),
			Translate(smallRing, vector3.New(-1., -1., 0.).Scale(quarterDim)),
			Box(middleCord3D, middleCord3D),
		),
	)

	for i := 0; i < 100; i++ {
		evaluateAtDepth(dimension, field, float64(-dimension/2)+(float64(i*dimension)*0.01), i)
	}
}

vector's People

Contributors

actions-user avatar dependabot[bot] avatar elicdavis avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

dseeni igadmg

vector's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.