Skip to content
Snippets Groups Projects
AbstractLineFact.cs 9.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • using Newtonsoft.Json;
    using System.Collections.Generic;
    using TMPro;
    using UnityEngine;
    
    
    /// <summary>
    /// Base-class for 1D-Facts
    /// </summary>
    public abstract class AbstractLineFact : FactWrappedCRTP<AbstractLineFact>
    {
        /// @{ <summary>
        /// One <see cref="Fact.Id">Id</see> of two <see cref="PointFact"/> defining <see cref="Dir"/>.
        /// </summary>
        public string Pid1, Pid2;
        /// @}
    
    
    MaZiFAU's avatar
    MaZiFAU committed
        public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
    
    MaZiFAU's avatar
    MaZiFAU committed
        public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
    
    MaZiFAU's avatar
    MaZiFAU committed
        /// <summary> Distance between <see cref="AbstractLineFact.Pid1"/> and <see cref="AbstractLineFact.Pid2"/></summary>
        [JsonIgnore]
        public float Distance;
    
    
        /// <summary>
        /// Normalized Direction from <see cref="Pid1"/> to <see cref="Pid2"/>.
        /// </summary>
        public Vector3 Dir;
    
        /// <summary>
        /// \copydoc Fact.Fact()
        /// </summary>
        protected AbstractLineFact() : base()
        {
            Pid1 = null;
            Pid2 = null;
            Dir = Vector3.zero;
        }
    
        /// <summary>
        /// Standard Constructor
        /// </summary>
        /// <param name="pid1">sets <see cref="AbstractLineFact.Pid1"/></param>
        /// <param name="pid2">sets <see cref="AbstractLineFact.Pid2"/></param>
        /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
        protected AbstractLineFact(string pid1, string pid2, FactOrganizer organizer) : base(organizer)
        {
            set_public_members(pid1, pid2);
        }
    
        /// <summary>
        /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
        /// </summary>
        /// <param name="pid1">sets <see cref="Pid1"/></param>
        /// <param name="pid2">sets <see cref="Pid2"/></param>
        /// <param name="backendURI">MMT URI</param>
        /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
        protected AbstractLineFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(organizer)
        {
            this._URI = backendURI;
    
        }
    
        /// <summary>
        /// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Dir"/>
        /// </summary>
        /// <param name="pid1">sets <see cref="Pid1"/></param>
        /// <param name="pid2">sets <see cref="Pid2"/></param>
        private void set_public_members(string pid1, string pid2)
        {
            this.Pid1 = pid1;
            this.Pid2 = pid2;
    
    MaZiFAU's avatar
    MaZiFAU committed
            Vector3 diff = (Point1.Point - Point2.Point);
            this.Dir = diff.normalized;
            this.Distance = diff.magnitude;
        }
    
    
    MaZiFAU's avatar
    MaZiFAU committed
        protected override void RecalculateTransform()
    
    MaZiFAU's avatar
    MaZiFAU committed
        {
    
    MaZiFAU's avatar
    MaZiFAU committed
            Position = Vector3.Lerp(Point1.Point, Point2.Point, 0.5f);
            Rotation = Quaternion.LookRotation(Dir, Vector3.up);
    
    MaZiFAU's avatar
    MaZiFAU committed
            LocalScale = new Vector3(1, 1, Distance);
    
        }
    
        /// \copydoc Fact.hasDependentFacts
    
        public override bool HasDependentFacts => true;
    
    
        /// \copydoc Fact.getDependentFactIds
    
        protected override string[] GetGetDependentFactIds() 
            => new string[] { Pid1, Pid2 };
    
    }
    
    /// <summary>
    /// Implements CRTP for <see cref="AbstractLineFact"/>; Escalates constructors;
    /// </summary>
    /// <typeparam name="T">class, which inherits from AbstractLineFactWrappedCRTP</typeparam>
    public abstract class AbstractLineFactWrappedCRTP<T> : AbstractLineFact where T : AbstractLineFactWrappedCRTP<T>
    {
        /// <summary>\copydoc Fact.Fact</summary>
        protected AbstractLineFactWrappedCRTP() : base() { }
    
        /// <summary>\copydoc AbstractLineFact.AbstractLineFact(string, string, FactOrganizer)</summary>
        protected AbstractLineFactWrappedCRTP(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer) { }
    
        /// <summary>\copydoc AbstractLineFact.AbstractLineFact(string, string, string, FactOrganizer)</summary>
        protected AbstractLineFactWrappedCRTP(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer) { }
    
        /// \copydoc Fact.Equivalent(Fact, Fact)
        protected override bool EquivalentWrapped(AbstractLineFact f1, AbstractLineFact f2)
            => EquivalentWrapped((T)f1, (T)f2);
    
        /// <summary>CRTP step of <see cref="EquivalentWrapped(AbstractLineFact, AbstractLineFact)"/></summary>
        protected abstract bool EquivalentWrapped(T f1, T f2);
    }
    
    /// <summary>
    /// Line within 3D Space of finite length
    /// </summary>
    public class LineFact : AbstractLineFactWrappedCRTP<LineFact>
    {
        /// \copydoc Fact.s_type
        [JsonProperty]
        protected static new string s_type = "LineFact";
    
        /// <summary> \copydoc Fact.Fact </summary>
    
    MaZiFAU's avatar
    MaZiFAU committed
        public LineFact() : base() { }
    
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, string, FactOrganizer) </summary>
    
    MaZiFAU's avatar
    MaZiFAU committed
        public LineFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer)
    
    MaZiFAU's avatar
    MaZiFAU committed
            => _ = this.Label;
    
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, FactOrganizer) </summary>
        public LineFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer)
    
    MaZiFAU's avatar
    MaZiFAU committed
            SendToMMT();
    
    MaZiFAU's avatar
    MaZiFAU committed
        public override MMTDeclaration MakeMMTDeclaration()
    
                new OMA(
    
                        new OMS(Pid1),
                        new OMS(Pid2)
    
            SOMDoc valueTp = new OMS(MMT_OMS_URI.RealLit);
    
    MaZiFAU's avatar
    MaZiFAU committed
            SOMDoc value = new OMF(Distance);
    
            return new MMTValueDeclaration(this.Label, lhs, valueTp, value);
    
        /// \copydoc Fact.parseFact(ScrollFact)
        public new static LineFact parseFact(MMTDeclaration fact)
    
            string pointAUri = ((OMS)((OMA)((MMTValueDeclaration)fact).lhs).arguments[0]).uri;
            string pointBUri = ((OMS)((OMA)((MMTValueDeclaration)fact).lhs).arguments[1]).uri;
    
    MaZiFAU's avatar
    MaZiFAU committed
            if (!FactOrganizer.AllFacts.ContainsKey(pointAUri)
             || !FactOrganizer.AllFacts.ContainsKey(pointBUri))
                return null;
    
    MaZiFAU's avatar
    MaZiFAU committed
            return new LineFact(pointAUri, pointBUri, fact.@ref.uri, StageStatic.stage.factState);
    
        }
    
        /// \copydoc Fact.generateLabel
        protected override string generateLabel()
    
    MaZiFAU's avatar
    MaZiFAU committed
            => "[" + Point1.Label + Point2.Label + "]";
    
    
        /// \copydoc Fact.Equivalent(Fact, Fact)
        protected override bool EquivalentWrapped(LineFact f1, LineFact f2)
    
    MaZiFAU's avatar
    MaZiFAU committed
            => DependentFactsEquivalent(f1, f2);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
        protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
            => new LineFact(old_to_new[this.Pid1], old_to_new[this.Pid2], organizer);
    
    }
    
    /// <summary>
    /// Ray within 3D Space of infinite length
    /// </summary>
    public class RayFact : AbstractLineFactWrappedCRTP<RayFact>
    {
        /// \copydoc Fact.s_type
        [JsonProperty]
        protected static new string s_type = "RayFact";
    
        /// <summary> \copydoc Fact.Fact </summary>
        public RayFact() : base() { }
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, string, FactOrganizer) </summary>
    
    MaZiFAU's avatar
    MaZiFAU committed
        public RayFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer)
    
    
        /// <summary> \copydoc AbstractLineFact.AbstractLineFact(string, string, FactOrganizer) </summary>
        public RayFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer)
    
    MaZiFAU's avatar
    MaZiFAU committed
            SendToMMT();
    
    MaZiFAU's avatar
    MaZiFAU committed
        public override MMTDeclaration MakeMMTDeclaration()
    
            SOMDoc type = new OMS(MMT_OMS_URI.LineType);
            SOMDoc defines = 
                new OMA(
                    new OMS(MMT_OMS_URI.LineOf),
                    new List<SOMDoc> {
                        new OMS(Pid1),
                        new OMS(Pid2)
    
            return new MMTSymbolDeclaration(this.Label, type, defines);
    
    MaZiFAU's avatar
    MaZiFAU committed
        }
    
    
        /// \copydoc Fact.parseFact(ScrollFact)
        public new static RayFact parseFact(MMTDeclaration fact)
    
    MaZiFAU's avatar
    MaZiFAU committed
            if (((MMTSymbolDeclaration)fact).defines is not OMA defines)
    
                return null;
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            string pointAUri = ((OMS)defines.arguments[0]).uri;
            string pointBUri = ((OMS)defines.arguments[1]).uri;
    
    MaZiFAU's avatar
    MaZiFAU committed
            if (!FactOrganizer.AllFacts.ContainsKey(pointAUri)
             || !FactOrganizer.AllFacts.ContainsKey(pointBUri))
                return null;
    
    MaZiFAU's avatar
    MaZiFAU committed
            return new RayFact(pointAUri, pointBUri, fact.@ref.uri, StageStatic.stage.factState);
    
        protected override void RecalculateTransform()
        {
            base.RecalculateTransform();
            LocalScale = new Vector3(1, 1, 2048);
        }
    
    
        /// \copydoc Fact.generateLabel
        protected override string generateLabel()
        {
            // TODO this string is too large to properly depict on scrolls. 
    
            // return "]" + Point1.Label + Point2.Label + "[";
    
    MaZiFAU's avatar
    MaZiFAU committed
            return Point1.Label + Point2.Label;
    
        }
    
        /// \copydoc Fact.Equivalent(Fact, Fact)
        protected override bool EquivalentWrapped(RayFact f1, RayFact f2)
        {
            if (!Math3d.IsApproximatelyParallel(f1.Dir, f2.Dir))
                return false;
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            return Math3d.IsPointApproximatelyOnLine(f1.Point1.Point, f1.Dir, f2.Point1.Point)
                && Math3d.IsPointApproximatelyOnLine(f1.Point1.Point, f1.Dir, f2.Point2.Point);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
        protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
            => new RayFact(old_to_new[this.Pid1], old_to_new[this.Pid2], organizer);