UnsortedFact.cs 18.16 KiB
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);
}