diff --git a/engine-proto/engine.jl b/engine-proto/engine.jl new file mode 100644 index 0000000..df75fbe --- /dev/null +++ b/engine-proto/engine.jl @@ -0,0 +1,105 @@ +module Engine + +export Construction, mprod + +import Subscripts +using LinearAlgebra +using AbstractAlgebra +using Groebner + +# --- primitve elements --- + +mutable struct Point{T} + coords::Union{Vector{MPolyRingElem{T}}, Nothing} + vec::Union{Vector{MPolyRingElem{T}}, Nothing} + + ## [to do] constructor argument never needed? + Point{T}(vec::Union{Vector{MPolyRingElem{T}}, Nothing} = nothing) where T = new(vec) +end + +coordnames(_::Point) = [:xₚ, :yₚ, :zₚ] + +function buildvec(pt::Point, coordqueue) + pt.coords = splice!(coordqueue, 1:3) + coordring = parent(coordqueue[1]) + pt.vec = [one(coordring), dot(pt.coords, pt.coords), pt.coords...] +end + +mutable struct Sphere{T} + coords::Union{Vector{MPolyRingElem{T}}, Nothing} + vec::Union{Vector{MPolyRingElem{T}}, Nothing} + + Sphere{T}(vec::Union{Vector{MPolyRingElem{T}}, Nothing} = nothing) where T = new(vec) +end + +coordnames(_::Sphere) = [:rₛ, :sₛ, :xₛ, :yₛ, :zₛ] + +function buildvec(sph::Sphere, coordqueue) + sph.coords = splice!(coordqueue, 1:5) + sph.vec = sph.coords +end + +# --- primitive relations --- + +abstract type Relation{T} end + +mprod(v, w) = v[1]*w[2] + w[1]*v[2] - dot(v[3:end], w[3:end]) + +struct LiesOn{T} <: Relation{T} + pt::Point{T} + sph::Sphere{T} +end + +struct AlignsWithBy{T} <: Relation{T} + sph_v::Sphere{T} + sph_w::Sphere{T} + cos_angle::T +end + +# --- constructions --- + +mutable struct Construction{T} + points::Vector{Point{T}} + spheres::Vector{Sphere{T}} + + Construction{T}(; points = Point{T}[], spheres = Sphere{T}[]) where T = new{T}(points, spheres) +end + +function Base.push!(ctx::Construction{T}, elem::Point{T}) where T + push!(ctx.points, elem) +end + +function Base.push!(ctx::Construction{T}, elem::Sphere{T}) where T + push!(ctx.spheres, elem) +end + +function realize(ctx::Construction{T}) where T + # collect variable names + allcoordnames = Symbol[] + elements = vcat(ctx.points, ctx.spheres) + for (index, elem) in enumerate(elements) + subscript = Subscripts.sub(string(index)) + append!(allcoordnames, + [Symbol(name, subscript) for name in coordnames(elem)] + ) + end + + # construct coordinate ring + coordring, coordqueue = polynomial_ring(parent_type(T)(), allcoordnames) + + # construct coordinate vectors + for elem in elements + buildvec(elem, coordqueue) + end +end + +end + +# ~~~ sandbox setup ~~~ + +a = Engine.Point{Rational{Int64}}() +b = Engine.Point{Rational{Int64}}() +s = Engine.Sphere{Rational{Int64}}() +ctx = Engine.Construction{Rational{Int64}}(points = [a]) +Engine.push!(ctx, b) +Engine.push!(ctx, s) \ No newline at end of file