diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs index 54da885ef4ca7b568b40fb80e6497a759f0531e6..d61e1d64b6871a3b75bf03e1892f786efd2ede1b 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs @@ -612,545 +612,6 @@ protected bool DependentFactsEquivalent(T f1, T f2) .All(b => b); } -/// <summary> -/// Point in 3D Space -/// </summary> -public class PointFact : FactWrappedCRTP<PointFact> -{ - /// <summary> Position </summary> - public Vector3 Point; - /// <summary> Orientation for <see cref="Fact.WorldRepresentation"/> </summary> - [JsonProperty] - private Vector3 Normal; - - /// <summary> \copydoc Fact.Fact </summary> - public PointFact() : base() - { - this.Point = Vector3.zero; - this.Normal = Vector3.up; - } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Point"/>, <see cref="Normal"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="P">sets <see cref="Point"/></param> - /// <param name="N">sets <see cref="Normal"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public PointFact(Vector3 P, Vector3 N, FactRecorder organizer) : base(organizer) - { - this.Point = P; - this.Normal = N; - } - - protected override void RecalculateTransform() - { - Position = Point; - { // Rotation - Vector3 notNormal = Vector3.forward != Normal ? Vector3.forward : Vector3.up; - Rotation = Quaternion.LookRotation( - Vector3.Cross(Normal, notNormal), - Normal - ); - } - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// <see cref="Normal"/> set to <c>Vector3.up</c> - /// </summary> - /// <param name="point">sets <see cref="Point"/></param> - /// <param name="uri">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public PointFact(Vector3 point, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) - { - this.Point = point; - this.Normal = Vector3.up; - this.ServerDefinition = _ServerDefinition; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) - { - if (((MMTGeneralFact)fact).defines is not OMA defines) - yield break; - ParsingDictionary.parseTermsToId.TryAdd(defines.ToString(), fact.@ref.uri); - - Vector3 point = SOMDoc.MakeVector3(defines); - ret.Add(new PointFact(point, fact.@ref, StageStatic.stage.factState)); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => false; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetDependentFactIds() - => new string[] { }; - - /// \copydoc Fact.GetHashCode - public override int GetHashCode() - => this.Point.GetHashCode(); - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(PointFact f1, PointFact f2) - => Math3d.IsApproximatelyEqual(f1.Point, f2.Point); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new PointFact(this.Point, this.Normal, organizer); - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = new OMS(MMTConstants.Point); - - return new MMTGeneralFact(Label, tp, Defines()); - } - - public override SOMDoc Defines() - => new OMA( - new OMS(MMTConstants.Tuple), - new[] { - new OMLIT<float>(Point.x), - new OMLIT<float>(Point.y), - new OMLIT<float>(Point.z), - } - ); -} - -/// <summary> -/// A <see cref="PointFact"/> on a <see cref="AbstractLineFact"/> -/// </summary> -public class OnLineFact : FactWrappedCRTP<OnLineFact> -{ - /// <summary> <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary> - public string Pid; - [JsonIgnore] - public PointFact Point { get => (PointFact)FactRecorder.AllFacts[Pid]; } - - /// <summary> <see cref="AbstractLineFact"/>.<see cref="Fact.Id">Id</see> </summary> - public string Rid; - [JsonIgnore] - public AbstractLineFact Ray { get => (AbstractLineFact)FactRecorder.AllFacts[Rid]; } - - /// <summary> \copydoc Fact.Fact </summary> - public OnLineFact() : base() - { - this.Pid = null; - this.Rid = null; - } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Pid"/>, <see cref="Rid"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="pid">sets <see cref="Pid"/></param> - /// <param name="rid">sets <see cref="Rid"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public OnLineFact(string pid, string rid, FactRecorder organizer) : base(organizer) - { - this.Pid = pid; - this.Rid = rid; - } - - protected override void RecalculateTransform() - { - Position = Point.Position; - { //Rotation - Vector3 up = Point.Rotation * Vector3.up; - Vector3 forward = Ray.Dir; - - if (Math3d.IsApproximatelyEqual(up, forward)) - { - Vector3 arbitary = Math3d.IsApproximatelyEqual(forward, Vector3.forward) - ? Vector3.right - : Vector3.forward; - - up = Vector3.Cross(arbitary, forward); - } - - Rotation = Quaternion.LookRotation(forward, up); - } - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="pid">sets <see cref="Pid"/></param> - /// <param name="rid">sets <see cref="Rid"/></param> - /// <param name="uri">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public OnLineFact(string pid, string rid, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) - { - this.Pid = pid; - this.Rid = rid; - this.ServerDefinition = _ServerDefinition; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) - { - string pointUri = ((OMS)((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[1]).uri; - string lineUri = ((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[0] is OMS - // standard case - ? ((OMS)((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[0]).uri - // case when line Uri has a projl on the line Argument - : ((OMS)((OMA)((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[0]).arguments[0]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(pointUri) - || !FactRecorder.AllFacts.ContainsKey(lineUri)) - yield break; - - ret.Add(new OnLineFact(pointUri, lineUri, fact.@ref, StageStatic.stage.factState)); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => Point.Label + "∈" + Ray.Label; - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetDependentFactIds() - => new string[] { Pid, Rid }; - - protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new OnLineFact(old_to_new[this.Pid], old_to_new[this.Rid], organizer); - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = new OMA( - new OMS(MMTConstants.Ded), - new[] { - new OMA( - new OMS(MMTConstants.OnLine), - new[] { - new OMS(Rid), - new OMS(Pid) - }),}); - - return new MMTGeneralFact(this.Label, tp, Defines()); - } - - public override SOMDoc Defines() => null; -} - -/// <summary> -/// Two parallel Lines comprised of two <see cref="LineFact">LineFacts</see> -/// </summary> -public class ParallelLineFact : FactWrappedCRTP<ParallelLineFact> -{ - /// @{ <summary> - /// One <see cref="Fact.Id">Id</see> of two <see cref="LineFact"/> that are parallel [<see cref="Lid1"/>, <see cref="Lid2"/>]. - /// </summary> - public string Lid1, Lid2; - /// @} - - [JsonIgnore] - public AbstractLineFact Ray1 { get => (AbstractLineFact)FactRecorder.AllFacts[Lid1]; } - [JsonIgnore] - public AbstractLineFact Ray2 { get => (AbstractLineFact)FactRecorder.AllFacts[Lid2]; } - - /// <summary> \copydoc Fact.Fact </summary> - public ParallelLineFact() : base() - { - this.Lid1 = null; - this.Lid2 = null; - } - - /// <summary> - /// Standard Constructor - /// </summary> - /// <param name="lid1">sets <see cref="Lid1"/></param> - /// <param name="lid2">sets <see cref="Lid2"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public ParallelLineFact(string lid1, string lid2, FactRecorder organizer) : base(organizer) - { - this.Lid1 = lid1; - this.Lid2 = lid2; - } - - protected override void RecalculateTransform() { } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Lid1">sets <see cref="Lid1"/></param> - /// <param name="Lid2">sets <see cref="Lid2"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public ParallelLineFact(string Lid1, string Lid2, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) - { - this.Lid1 = Lid1; - this.Lid2 = Lid2; - - this.ServerDefinition = _ServerDefinition; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) - { - if (((MMTGeneralFact)fact).type is not OMA type) // proof DED - yield break; - - OMA parallel_lines_OMA = (OMA)type.arguments[0]; // parallel - - string lineAUri = ((OMS)parallel_lines_OMA.arguments[0]).uri; - string lineBUri = ((OMS)parallel_lines_OMA.arguments[1]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(lineAUri) - || !FactRecorder.AllFacts.ContainsKey(lineBUri)) - yield break; - - ret.Add(new ParallelLineFact(lineAUri, lineBUri, fact.@ref, StageStatic.stage.factState)); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => Ray1.Label + "||" + Ray2.Label; - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = new OMA( - new OMS(MMTConstants.Ded), - new[] { - new OMA( - new OMS(MMTConstants.ParallelLine), - new[] { - new OMS(Lid1), - new OMS(Lid2), - } - ), - } - ); - - return new MMTGeneralFact(this.Label, tp, Defines()); - } - - public override SOMDoc Defines() => null; - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetDependentFactIds() - => new string[] { Lid1, Lid2 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(ParallelLineFact f1, ParallelLineFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new ParallelLineFact(old_to_new[this.Lid1], old_to_new[this.Lid2], organizer); -} - -/// <summary> -/// Used for BouncingScroll -/// </summary> -public class QuadFact : FactWrappedCRTP<QuadFact> -{ - /// <summary> Defining Corners; Order is Cyclic; - /// <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary> - public string[] Pids; - [JsonIgnore] - public PointFact[] Points - { - get => _Points ??= Pids.Select(pid => (PointFact)FactRecorder.AllFacts[pid]).ToArray(); - } - private PointFact[] _Points; - - [JsonIgnore] - public Vector3 Normal, Tangents, AltTangents; - - /// <summary> \copydoc Fact.Fact </summary> - public QuadFact() : base() { } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Pids"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="pid_corners">sets <see cref="Pids"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public QuadFact(string[] pid_corners, FactRecorder organizer) : base(organizer) - { - Init(pid_corners); - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="pid_corners">sets <see cref="Pids"/></param> - /// <param name="uri">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public QuadFact(string[] pid_corners, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) - { - Init(pid_corners); - - this.ServerDefinition = _ServerDefinition; - _ = this.Label; - } - - private void Init(string[] pid_corners) - { - Pids = pid_corners; - - Tangents = (Points[0].Point - Points[1].Point).normalized; - AltTangents = (Points[0].Point - Points[2].Point).normalized; - Normal = Vector3.Cross(Tangents, AltTangents).normalized; - - if (Math3d.vectorPrecission < Math.Abs(Vector3.Dot(Normal, Points[0].Point - Points[3].Point))) - throw new ArgumentException("All Points must lie on the same Plane!"); - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) - { - throw new NotImplementedException(); - } - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = new OMS(MMTConstants.Wall); - - return new MMTGeneralFact(Label, tp, Defines()); - } - - public override SOMDoc Defines() - => new OMA( - new OMS(MMTConstants.CreateWall), - Pids.Select(pid => new OMS(pid)).ToArray() - ); - - protected override bool EquivalentWrapped(QuadFact f1, QuadFact f2) - { - if (f1.Points.Length != f2.Points.Length) - return false; - - int i = 0; - for (; i < f2.Points.Length; i++) // 1st incedence - if (f2.Points[i].Equivalent(f1.Points[0])) - break; - - if (i == f2.Points.Length) // no match - return false; - - for (int j = 1; j < f2.Points.Length; j++) // cyclic match - if (!f2.Points[(i + j) % f2.Points.Length].Equivalent(f1.Points[j])) - return false; - - return true; - } - - public override bool HasDependentFacts => true; - - protected override string[] GetDependentFactIds() - => Pids; - - protected override void RecalculateTransform() { } - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new QuadFact(Pids.Select(pid => old_to_new[pid]).ToArray(), organizer); -} - -/// <summary> -/// Used for BouncingScroll -/// </summary> -public class TriangleFact : FactWrappedCRTP<TriangleFact> -{ - /// <summary> Defining Verticies; Order gives NormalDirection; - public Vector3[] Verticies; - - [JsonIgnore] - public Vector3 Normal, Tangents, AltTangents; - - /// <summary> \copydoc Fact.Fact </summary> - public TriangleFact() : base() { } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Pids"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="pid_corners">sets <see cref="Pids"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public TriangleFact(Vector3[] Verticies, FactRecorder organizer) : base(organizer) - { - Init(Verticies); - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="pid_corners">sets <see cref="Pids"/></param> - /// <param name="uri">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public TriangleFact(Vector3[] Verticies, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) - { - Init(Verticies); - - this.ServerDefinition = _ServerDefinition; - _ = this.Label; - } - - private void Init(Vector3[] Verticies) - { - this.Verticies = Verticies; - - Tangents = (Verticies[0] - Verticies[1]).normalized; - AltTangents = (Verticies[0] - Verticies[2]).normalized; - Normal = Vector3.Cross(Tangents, AltTangents).normalized; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) - { - throw new NotImplementedException(); - } - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = new OMS(MMTConstants.Triangle); - - return new MMTGeneralFact(Label, tp, Defines()); - } - - public override SOMDoc Defines() - => new OMA( - new OMS(MMTConstants.CreateTriangle), - Verticies.Select(vert => SOMDoc.MakeVector3(vert)).ToArray() - ); - - protected override bool EquivalentWrapped(TriangleFact f1, TriangleFact f2) - { - int i = 0; - for (; i < 3; i++) - if (Math3d.IsApproximatelyEqual(f2.Verticies[i], f1.Verticies[0])) - break; // 1st incedence - - return i < 3 // match ? then do: cyclic match - && Math3d.IsApproximatelyEqual(f2.Verticies[(i + 1) % 3], f1.Verticies[1]) - && Math3d.IsApproximatelyEqual(f2.Verticies[(i + 2) % 3], f1.Verticies[2]); - } - - public override bool HasDependentFacts => false; - - protected override string[] GetDependentFactIds() - => new string[0]; - - protected override void RecalculateTransform() - { - Position = Verticies[0]; - Rotation = Quaternion.LookRotation(Tangents, Vector3.up); - } - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new TriangleFact(Verticies, organizer); -} - #pragma warning disable // Testing... /// TEST FACT diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/UnsortedFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/UnsortedFact.cs new file mode 100644 index 0000000000000000000000000000000000000000..95bae89c01b219234e0a2f27f9a9865901e971a4 --- /dev/null +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/UnsortedFact.cs @@ -0,0 +1,546 @@ +using Newtonsoft.Json; +using REST_JSON_API; +using System.Collections.Generic; +using System.Linq; +using System; +using UnityEngine; +using System.Collections; + +/// <summary> +/// Point in 3D Space +/// </summary> +public class PointFact : FactWrappedCRTP<PointFact> +{ + /// <summary> Position </summary> + public Vector3 Point; + /// <summary> Orientation for <see cref="Fact.WorldRepresentation"/> </summary> + [JsonProperty] + private Vector3 Normal; + + /// <summary> \copydoc Fact.Fact </summary> + public PointFact() : base() + { + this.Point = Vector3.zero; + this.Normal = Vector3.up; + } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Point"/>, <see cref="Normal"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="P">sets <see cref="Point"/></param> + /// <param name="N">sets <see cref="Normal"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public PointFact(Vector3 P, Vector3 N, FactRecorder organizer) : base(organizer) + { + this.Point = P; + this.Normal = N; + } + + protected override void RecalculateTransform() + { + Position = Point; + { // Rotation + Vector3 notNormal = Vector3.forward != Normal ? Vector3.forward : Vector3.up; + Rotation = Quaternion.LookRotation( + Vector3.Cross(Normal, notNormal), + Normal + ); + } + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// <see cref="Normal"/> set to <c>Vector3.up</c> + /// </summary> + /// <param name="point">sets <see cref="Point"/></param> + /// <param name="uri">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public PointFact(Vector3 point, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) + { + this.Point = point; + this.Normal = Vector3.up; + this.ServerDefinition = _ServerDefinition; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) + { + if (((MMTGeneralFact)fact).defines is not OMA defines) + yield break; + ParsingDictionary.parseTermsToId.TryAdd(defines.ToString(), fact.@ref.uri); + + Vector3 point = SOMDoc.MakeVector3(defines); + ret.Add(new PointFact(point, fact.@ref, StageStatic.stage.factState)); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => false; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { }; + + /// \copydoc Fact.GetHashCode + public override int GetHashCode() + => this.Point.GetHashCode(); + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(PointFact f1, PointFact f2) + => Math3d.IsApproximatelyEqual(f1.Point, f2.Point); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new PointFact(this.Point, this.Normal, organizer); + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMS(MMTConstants.Point); + + return new MMTGeneralFact(Label, tp, Defines()); + } + + public override SOMDoc Defines() + => new OMA( + new OMS(MMTConstants.Tuple), + new[] { + new OMLIT<float>(Point.x), + new OMLIT<float>(Point.y), + new OMLIT<float>(Point.z), + } + ); +} + +/// <summary> +/// A <see cref="PointFact"/> on a <see cref="AbstractLineFact"/> +/// </summary> +public class OnLineFact : FactWrappedCRTP<OnLineFact> +{ + /// <summary> <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary> + public string Pid; + [JsonIgnore] + public PointFact Point { get => (PointFact)FactRecorder.AllFacts[Pid]; } + + /// <summary> <see cref="AbstractLineFact"/>.<see cref="Fact.Id">Id</see> </summary> + public string Rid; + [JsonIgnore] + public AbstractLineFact Ray { get => (AbstractLineFact)FactRecorder.AllFacts[Rid]; } + + /// <summary> \copydoc Fact.Fact </summary> + public OnLineFact() : base() + { + this.Pid = null; + this.Rid = null; + } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Pid"/>, <see cref="Rid"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="pid">sets <see cref="Pid"/></param> + /// <param name="rid">sets <see cref="Rid"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public OnLineFact(string pid, string rid, FactRecorder organizer) : base(organizer) + { + this.Pid = pid; + this.Rid = rid; + } + + protected override void RecalculateTransform() + { + Position = Point.Position; + { //Rotation + Vector3 up = Point.Rotation * Vector3.up; + Vector3 forward = Ray.Dir; + + if (Math3d.IsApproximatelyEqual(up, forward)) + { + Vector3 arbitary = Math3d.IsApproximatelyEqual(forward, Vector3.forward) + ? Vector3.right + : Vector3.forward; + + up = Vector3.Cross(arbitary, forward); + } + + Rotation = Quaternion.LookRotation(forward, up); + } + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="pid">sets <see cref="Pid"/></param> + /// <param name="rid">sets <see cref="Rid"/></param> + /// <param name="uri">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public OnLineFact(string pid, string rid, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) + { + this.Pid = pid; + this.Rid = rid; + this.ServerDefinition = _ServerDefinition; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) + { + string pointUri = ((OMS)((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[1]).uri; + string lineUri = ((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[0] is OMS + // standard case + ? ((OMS)((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[0]).uri + // case when line Uri has a projl on the line Argument + : ((OMS)((OMA)((OMA)((OMA)((MMTGeneralFact)fact).type).arguments[0]).arguments[0]).arguments[0]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(pointUri) + || !FactRecorder.AllFacts.ContainsKey(lineUri)) + yield break; + + ret.Add(new OnLineFact(pointUri, lineUri, fact.@ref, StageStatic.stage.factState)); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => Point.Label + "∈" + Ray.Label; + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Pid, Rid }; + + protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new OnLineFact(old_to_new[this.Pid], old_to_new[this.Rid], organizer); + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMA( + new OMS(MMTConstants.Ded), + new[] { + new OMA( + new OMS(MMTConstants.OnLine), + new[] { + new OMS(Rid), + new OMS(Pid) + }),}); + + return new MMTGeneralFact(this.Label, tp, Defines()); + } + + public override SOMDoc Defines() => null; +} + +/// <summary> +/// Two parallel Lines comprised of two <see cref="LineFact">LineFacts</see> +/// </summary> +public class ParallelLineFact : FactWrappedCRTP<ParallelLineFact> +{ + /// @{ <summary> + /// One <see cref="Fact.Id">Id</see> of two <see cref="LineFact"/> that are parallel [<see cref="Lid1"/>, <see cref="Lid2"/>]. + /// </summary> + public string Lid1, Lid2; + /// @} + + [JsonIgnore] + public AbstractLineFact Ray1 { get => (AbstractLineFact)FactRecorder.AllFacts[Lid1]; } + [JsonIgnore] + public AbstractLineFact Ray2 { get => (AbstractLineFact)FactRecorder.AllFacts[Lid2]; } + + /// <summary> \copydoc Fact.Fact </summary> + public ParallelLineFact() : base() + { + this.Lid1 = null; + this.Lid2 = null; + } + + /// <summary> + /// Standard Constructor + /// </summary> + /// <param name="lid1">sets <see cref="Lid1"/></param> + /// <param name="lid2">sets <see cref="Lid2"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public ParallelLineFact(string lid1, string lid2, FactRecorder organizer) : base(organizer) + { + this.Lid1 = lid1; + this.Lid2 = lid2; + } + + protected override void RecalculateTransform() { } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Lid1">sets <see cref="Lid1"/></param> + /// <param name="Lid2">sets <see cref="Lid2"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public ParallelLineFact(string Lid1, string Lid2, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) + { + this.Lid1 = Lid1; + this.Lid2 = Lid2; + + this.ServerDefinition = _ServerDefinition; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) + { + if (((MMTGeneralFact)fact).type is not OMA type) // proof DED + yield break; + + OMA parallel_lines_OMA = (OMA)type.arguments[0]; // parallel + + string lineAUri = ((OMS)parallel_lines_OMA.arguments[0]).uri; + string lineBUri = ((OMS)parallel_lines_OMA.arguments[1]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(lineAUri) + || !FactRecorder.AllFacts.ContainsKey(lineBUri)) + yield break; + + ret.Add(new ParallelLineFact(lineAUri, lineBUri, fact.@ref, StageStatic.stage.factState)); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => Ray1.Label + "||" + Ray2.Label; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMA( + new OMS(MMTConstants.Ded), + new[] { + new OMA( + new OMS(MMTConstants.ParallelLine), + new[] { + new OMS(Lid1), + new OMS(Lid2), + } + ), + } + ); + + return new MMTGeneralFact(this.Label, tp, Defines()); + } + + public override SOMDoc Defines() => null; + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Lid1, Lid2 }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(ParallelLineFact f1, ParallelLineFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new ParallelLineFact(old_to_new[this.Lid1], old_to_new[this.Lid2], organizer); +} + +/// <summary> +/// Used for BouncingScroll +/// </summary> +public class QuadFact : FactWrappedCRTP<QuadFact> +{ + /// <summary> Defining Corners; Order is Cyclic; + /// <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary> + public string[] Pids; + [JsonIgnore] + public PointFact[] Points + { + get => _Points ??= Pids.Select(pid => (PointFact)FactRecorder.AllFacts[pid]).ToArray(); + } + private PointFact[] _Points; + + [JsonIgnore] + public Vector3 Normal, Tangents, AltTangents; + + /// <summary> \copydoc Fact.Fact </summary> + public QuadFact() : base() { } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Pids"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="pid_corners">sets <see cref="Pids"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public QuadFact(string[] pid_corners, FactRecorder organizer) : base(organizer) + { + Init(pid_corners); + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="pid_corners">sets <see cref="Pids"/></param> + /// <param name="uri">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public QuadFact(string[] pid_corners, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) + { + Init(pid_corners); + + this.ServerDefinition = _ServerDefinition; + _ = this.Label; + } + + private void Init(string[] pid_corners) + { + Pids = pid_corners; + + Tangents = (Points[0].Point - Points[1].Point).normalized; + AltTangents = (Points[0].Point - Points[2].Point).normalized; + Normal = Vector3.Cross(Tangents, AltTangents).normalized; + + if (Math3d.vectorPrecission < Math.Abs(Vector3.Dot(Normal, Points[0].Point - Points[3].Point))) + throw new ArgumentException("All Points must lie on the same Plane!"); + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) + { + throw new NotImplementedException(); + } + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMS(MMTConstants.Wall); + + return new MMTGeneralFact(Label, tp, Defines()); + } + + public override SOMDoc Defines() + => new OMA( + new OMS(MMTConstants.CreateWall), + Pids.Select(pid => new OMS(pid)).ToArray() + ); + + protected override bool EquivalentWrapped(QuadFact f1, QuadFact f2) + { + if (f1.Points.Length != f2.Points.Length) + return false; + + int i = 0; + for (; i < f2.Points.Length; i++) // 1st incedence + if (f2.Points[i].Equivalent(f1.Points[0])) + break; + + if (i == f2.Points.Length) // no match + return false; + + for (int j = 1; j < f2.Points.Length; j++) // cyclic match + if (!f2.Points[(i + j) % f2.Points.Length].Equivalent(f1.Points[j])) + return false; + + return true; + } + + public override bool HasDependentFacts => true; + + protected override string[] GetDependentFactIds() + => Pids; + + protected override void RecalculateTransform() { } + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new QuadFact(Pids.Select(pid => old_to_new[pid]).ToArray(), organizer); +} + +/// <summary> +/// Used for BouncingScroll +/// </summary> +public class TriangleFact : FactWrappedCRTP<TriangleFact> +{ + /// <summary> Defining Verticies; Order gives NormalDirection; + public Vector3[] Verticies; + + [JsonIgnore] + public Vector3 Normal, Tangents, AltTangents; + + /// <summary> \copydoc Fact.Fact </summary> + public TriangleFact() : base() { } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Pids"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="pid_corners">sets <see cref="Pids"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public TriangleFact(Vector3[] Verticies, FactRecorder organizer) : base(organizer) + { + Init(Verticies); + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="pid_corners">sets <see cref="Pids"/></param> + /// <param name="uri">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public TriangleFact(Vector3[] Verticies, SOMDoc _ServerDefinition, FactRecorder organizer) : base(organizer) + { + Init(Verticies); + + this.ServerDefinition = _ServerDefinition; + _ = this.Label; + } + + private void Init(Vector3[] Verticies) + { + this.Verticies = Verticies; + + Tangents = (Verticies[0] - Verticies[1]).normalized; + AltTangents = (Verticies[0] - Verticies[2]).normalized; + Normal = Vector3.Cross(Tangents, AltTangents).normalized; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact) + { + throw new NotImplementedException(); + } + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMS(MMTConstants.Triangle); + + return new MMTGeneralFact(Label, tp, Defines()); + } + + public override SOMDoc Defines() + => new OMA( + new OMS(MMTConstants.CreateTriangle), + Verticies.Select(vert => SOMDoc.MakeVector3(vert)).ToArray() + ); + + protected override bool EquivalentWrapped(TriangleFact f1, TriangleFact f2) + { + int i = 0; + for (; i < 3; i++) + if (Math3d.IsApproximatelyEqual(f2.Verticies[i], f1.Verticies[0])) + break; // 1st incedence + + return i < 3 // match ? then do: cyclic match + && Math3d.IsApproximatelyEqual(f2.Verticies[(i + 1) % 3], f1.Verticies[1]) + && Math3d.IsApproximatelyEqual(f2.Verticies[(i + 2) % 3], f1.Verticies[2]); + } + + public override bool HasDependentFacts => false; + + protected override string[] GetDependentFactIds() + => new string[0]; + + protected override void RecalculateTransform() + { + Position = Verticies[0]; + Rotation = Quaternion.LookRotation(Tangents, Vector3.up); + } + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new TriangleFact(Verticies, organizer); +} \ No newline at end of file