require 'mittsu/extras/geometries/parametric_buffer_geometry' module Mittsu class ParametricGeometry < Geometry def initialize(func, slices, stacks) super() @type = 'ParametricGeometry' @parameters = { func: func, slices: slices, stacks: stacks } from_buffer_geometry(ParametricBufferGeometry.new(func, slices, stacks)) merge_vertices end def self.klein -> (v, u, target = Vector3.new) { u *= ::Math::PI v *= 2.0 * ::Math::PI u = u * 2.0 x = nil y = nil z = nil if u < ::Math::PI x = 3.0 * ::Math.cos(u) * (1.0 + ::Math.sin(u)) + (2.0 * (1.0 - ::Math.cos(u) / 2.0)) * ::Math.cos(u) * ::Math.cos(v) z = -8.0 * ::Math.sin(u) - 2.0 * (1.0 - ::Math.cos(u) / 2.0) * ::Math.sin(u) * ::Math.cos(v) else x = 3.0 * ::Math.cos(u) * (1.0 + ::Math.sin(u)) + (2.0 * (1.0 - ::Math.cos(u) / 2.0)) * ::Math.cos(v + ::Math::PI) z = -8.0 * ::Math.sin(u) end y = -2.0 * (1.0 - ::Math.cos(u) / 2.0) * ::Math.sin(v) target.set(x, y, z) } end def self.plane(width, height) -> (u, v, target = Vector3.new) { x = u.to_f * width.to_f y = 0.0 z = v.to_f * height.to_f target.set(x, y, z) } end def self.mobius -> (u, t, target = Vector3.new) { # flat mobius strip # http://www.wolframalpha.com/input/?i=M%C3%B6bius+strip+parametric+equations&lk=1&a=ClashPrefs_*Surface.MoebiusStrip.SurfaceProperty.ParametricEquations- u = u - 0.5 v = 2.0 * ::Math::PI * t a = 2.0 x = ::Math.cos(v) * (a + u * ::Math.cos(v / 2.0)) y = ::Math.sin(v) * (a + u * ::Math.cos(v / 2.0)) z = u * ::Math.sin(v / 2) target.set(x, y, z) } end def self.mobius3d -> (u, t, target = Vector3.new) { # volumetric mobius strip u *= ::Math::PI t *= 2.0 * ::Math::PI u = u * 2.0 phi = u / 2.0 major = 2.25 a = 0.125 b = 0.65 x = a * ::Math.cos(t) * ::Math.cos(phi) - b * ::Math.sin(t) * ::Math.sin(phi) z = a * ::Math.cos(t) * ::Math.sin(phi) + b * ::Math.sin(t) * ::Math.cos(phi) y = (major + x) * ::Math.sin(u) x = (major + x) * ::Math.cos(u) target.set(x, y, z) } end end end