diff --git a/engine-proto/engine.jl b/engine-proto/engine.jl index 8b82b47..df75fbe 100644 --- a/engine-proto/engine.jl +++ b/engine-proto/engine.jl @@ -1,34 +1,105 @@ module Engine -export Construction, Sphere, mprod, point +export Construction, mprod +import Subscripts using LinearAlgebra +using AbstractAlgebra using Groebner -mutable struct Construction - nextid::Int64 +# --- primitve elements --- + +mutable struct Point{T} + coords::Union{Vector{MPolyRingElem{T}}, Nothing} + vec::Union{Vector{MPolyRingElem{T}}, Nothing} - Construction(; nextid = 0) = new(nextid) + ## [to do] constructor argument never needed? + Point{T}(vec::Union{Vector{MPolyRingElem{T}}, Nothing} = nothing) where T = new(vec) end -struct Sphere{T<:Number} - vec::Vector{T} - id +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} - function Sphere(vec::Vector{T}, ctx::Construction) where T <: Number - id = ctx.nextid - ctx.nextid += 1 - new{T}(vec, id) + 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 -function mprod(sv::Sphere, sw::Sphere) - v = sv.vec - w = sw.vec - v[1]*w[2] + v[2]*w[1] - dot(v[3:end], w[3:end]) end -point(pt::Vector{<:Number}, ctx::Construction) = - Sphere([one(eltype(pt)), dot(pt, pt), pt...], ctx) +# ~~~ sandbox setup ~~~ -end \ No newline at end of file +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