Skip to content
Snippets Groups Projects
SquareFact.cs 6.55 KiB
Newer Older
  • Learn to ignore specific revisions
  • Paul-Walcher's avatar
    Paul-Walcher committed
    using Newtonsoft.Json;
    using REST_JSON_API;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    
    /// <summary>
    /// Point in 3D Space
    /// </summary>
    public class SquareFact : FactWrappedCRTP<SquareFact>
    {
    
    
        //used points
        public string PidA, PidB, PidC;
    
        public Vector3 A, B, C, D;
    
    
    
        public PointFact GetA {get =>  (PointFact)FactRecorder.AllFacts[PidA];}
        public PointFact GetB {get =>  (PointFact)FactRecorder.AllFacts[PidB];}
        public PointFact GetC {get =>  (PointFact)FactRecorder.AllFacts[PidC];}
        protected void calculate_vectors(){
    
            A = ((PointFact)FactRecorder.AllFacts[PidA]).Point + Vector3.zero;
            B = ((PointFact)FactRecorder.AllFacts[PidB]).Point + Vector3.zero;
            C = ((PointFact)FactRecorder.AllFacts[PidC]).Point + Vector3.zero;
            D = (A - B) + C;
    
    
    Paul-Walcher's avatar
    Paul-Walcher committed
            Vector3 scale = new Vector3(Vector3.Distance(B, C), Vector3.Distance(A, B), 1.0F);
    
    Paul-Walcher's avatar
    Paul-Walcher committed
            
            LocalScale = scale * 0.5F;
    
    
            Position =  B + 0.5F*((A-B) + (C-B));
    
            //Vector3 normal = Vector3.Cross((A-B), (C-B)); s
            /*
             Vector3 arbitary_not_normal = normal == Vector3.forward ? Vector3.right : Vector3.forward;
            Vector3 forward = Vector3.Cross(arbitary_not_normal, normal);
    
            Rotation = Quaternion.LookRotation(forward, normal);
            */
    
            /*
            //angle rotation around y axis
            Vector3 AB = A - B;
            Vector3 BC = C - B;
    
            // Calculate the angle between AB and BC around the Y-axis
            float yAxisRotation = Mathf.Atan2(AB.z, AB.x) * Mathf.Rad2Deg;
            float xAxisRotation = Mathf.Atan2(BC.z, BC.y) * Mathf.Rad2Deg;
            float zAxisRotation = Mathf.Atan2(AB.y, AB.x) * Mathf.Rad2Deg;
    
            Vector3 rotationVector = new Vector3(0, yAxisRotation, 0);
            */
    
            //angle rotation around y axis
    
            /*
            float distABx = (A.x - B.x);
            float distABy = (A.y - B.y);
            float distABz = (A.z - B.z);
    
            float distBCx = (C.x - B.x);
            float distBCy = (C.y - B.y);
            float distBCz = (C.z - B.z);
    
            float ERROR = 1E-5F;
    
            float xAxisRotation = Mathf.Rad2Deg* - Mathf.Atan(distBCy / distBCz);
            float yAxisRotation = -(Mathf.Abs((distABx - distABz)) < ERROR ? 45.0F :  Mathf.Rad2Deg*Mathf.Atan(distABx / distABz));
            float zAxisRotation = Mathf.Rad2Deg*Mathf.Atan(distABy / distABx);
    
            Vector3 rotationVector = new Vector3(xAxisRotation, yAxisRotation, zAxisRotation);
    
            Rotation = Quaternion.Euler(rotationVector);
    
            */
    
            /*
            Vector3 forward = (from + to).normalized;
    
            if (up.sqrMagnitude < Math3d.vectorPrecission)
            { //Angle is 180° (or 0°)
                Vector3 from_arbitary = from.normalized == Vector3.forward ? Vector3.right : Vector3.forward;
                up = Vector3.Cross(from_arbitary, to);
                forward = Vector3.Cross(up, to);
            }
    
            Vector3 upy0 = new Vector3(up.x, 0, up.z);
            Rotation = Quaternion.LookRotation(upy0, up);
    
            Vector3 from = (A - B).normalized;
            Vector3 to = (C - B).normalized;
            Vector3 up = Vector3.Cross(from, to);
    
            Rotation = Quaternion.LookRotation(up, new Vector3(0.0F, 0.0F, 1.0F));
    
            Vector3 normal = Vector3.Cross((A-B), (B-C));
            lookObject.transform.position = normal + Position;
            */
    
    
    Paul-Walcher's avatar
    Paul-Walcher committed
            Rotation = Quaternion.LookRotation(Vector3.Cross((A-B), (C-B)), Vector3.up);
            //Rotation = Quaternion.LookRotation(forward, new Vector3(1.0F, 0.0F, 0.0F));
    
    Paul-Walcher's avatar
    Paul-Walcher committed
            
        }
    
        public SquareFact() : base(){
            this.PidA = null;
            this.PidB = null;
            this.PidC = null;
        }
        [JsonConstructor]
        public SquareFact( string PidA, string PidB, string PidC) : base()
        {
    
            this.PidA = PidA;
            this.PidB = PidB;
            this.PidC = PidC;
    
            calculate_vectors();
    
        }
    
        /// <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="ServerDefinition">MMT URI as OMS</param>
        public SquareFact(string PidA, string PidB, string PidC, SOMDoc ServerDefinition) : base()
        {
      
    
            this.PidA = PidA;
            this.PidB = PidB;
            this.PidC = PidC;
            
            this.ServerDefinition = ServerDefinition;
    
            calculate_vectors();
        
        }
    
        /// \copydoc Fact.parseFact(ScrollFact)
        public new static IEnumerator parseFact(List<Fact> ret, MMTFact fact)
        {
            if (((MMTGeneralFact)fact).defines is not OMA df)
                yield break;
    
            OMS pointA, pointB, pointC;
    
            pointA = (OMS)df.arguments[0];
            pointB = (OMS)df.arguments[1];
            pointC = (OMS)df.arguments[2];
    
            string PidA = pointA.uri;
            string PidB = pointB.uri;
            string PidC = pointC.uri;
    
            
    
            ret.Add(new SquareFact(PidA, PidB, PidC, fact.@ref));
    
            //ParsingDictionary.parseTermsToId.TryAdd(defines.ToString(), fact.@ref.uri);
            //ret.Add(new PointFact(SOMDoc.MakeVector3(defines), fact.@ref));
        }
    
    
        /// \copydoc Fact.hasDependentFacts
        public override bool HasDependentFacts => true;
    
        /// \copydoc Fact.getDependentFactIds
        protected override string[] GetDependentFactIds()
            => new string[] { PidA, PidB, PidC};
    
        /// \copydoc Fact.GetHashCode
        /* public override int GetHashCode()
            => this.Point.GetHashCode();
        */
        protected override void RecalculateTransform()
        {
            calculate_vectors();
        }
        /// \copydoc Fact.Equivalent(Fact, Fact)
        protected override bool EquivalentWrapped(SquareFact f1, SquareFact f2){
            
            return (
    
                        Math3d.IsApproximatelyEqual(f1.A, f2.A)
                    && Math3d.IsApproximatelyEqual(f1.B, f2.B)
                    && Math3d.IsApproximatelyEqual(f1.C, f2.C)
                    && Math3d.IsApproximatelyEqual(f1.D, f2.D)
    
            );
    
        }
    
        protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new){
            
            return new SquareFact(this.PidA, this.PidB, this.PidC);
    
        }
    
        public override MMTFact MakeMMTDeclaration()
        {
            SOMDoc tp = new OMS(MMTConstants.SquareType);
    
            return new MMTGeneralFact(_LastLabel, tp, Defines());
        }
    
        public override SOMDoc Defines()
            => new OMA(
                    new OMS(MMTConstants.SquareCons),
                    new[] {
                            new OMS(PidA),
                            new OMS(PidB),
                            new OMS(PidC),
                    }
                );
    }