Пример #1
0
        public static Matrix4x4 GetJacobi(IIntersect obj0, IIntersect obj1, Vector2 uv0, Vector2 uv1, Vector2 uvNew0, Vector2 uvNew1)
        {
            var dU0 = obj0.EvaluateDU(uv0);
            var dV0 = obj0.EvaluateDV(uv0);
            var dU1 = obj1.EvaluateDU(uv1);
            var dV1 = obj1.EvaluateDV(uv1);

            var normalT = GetTNormal(dU0, dU1, dV0, dV1);

            dU0 = obj0.EvaluateDU(uvNew0);
            dV0 = obj0.EvaluateDV(uvNew0);
            dU1 = -obj1.EvaluateDU(uvNew1);
            dV1 = -obj1.EvaluateDV(uvNew1);

            var dot1 = Vector3.Dot(dU0, normalT);
            var dot2 = Vector3.Dot(dV0, normalT);

            var jacobiMatrix = new Matrix4x4(
                dU0.X, dV0.X, dU1.X, dV1.X,
                dU0.Y, dV0.Y, dU1.Y, dV1.Y,
                dU0.Z, dV0.Z, dU1.Z, dV1.Z,
                dot1, dot2, 0, 0);

            Matrix4x4.Invert(jacobiMatrix, out Matrix4x4 inv);
            return(inv);
        }
Пример #2
0
        private static Vector4 GetNewtonIterationPoint(IIntersect obj0, IIntersect obj1, Vector2 uv0, Vector2 uv1, Vector2 uvNew0, Vector2 uvNew1, float alpha)
        {
            var mat = GetJacobi(obj0, obj1, uv0, uv1, uvNew0, uvNew1);
            var vec = GetF(obj0, obj1, uv0, uv1, uvNew0, uvNew1, alpha);

            return(vec.Multiply(mat));
        }
Пример #3
0
        public SceneBuilder AddGeoPrimitive(IIntersect shape, Material mat)
        {
            if (_rayTracer == null)
            {
                _rayTracer = new RayTracer();
            }

            _rayTracer.Primitives.Add(new GeometricPrimitive(shape, mat));

            return(this);
        }
Пример #4
0
        private static IntersectionCurve Gradient(IIntersect obj0, IIntersect obj1, Vector2 value0, Vector2 value1, float precision)
        {
            var p0 = obj0.Evaluate(value0);
            var p1 = obj1.Evaluate(value1);

            var i         = 0;
            var currAlpha = _startGradientAlpha;
            var dist      = Vector3.Distance(p1, p0);

            while (dist > _gradientEps)
            {
                if (++i > 10000)
                {
                    return(null);
                }

                try
                {
                    var grads = GetGradient(obj0, obj1, value0, value1);
                    value0 -= currAlpha * grads[0];
                    value1 -= currAlpha * grads[1];

                    value0.X = Math.Min(1, Math.Max(0, value0.X));
                    value0.Y = Math.Min(1, Math.Max(0, value0.Y));
                    value1.X = Math.Min(1, Math.Max(0, value1.X));
                    value1.Y = Math.Min(1, Math.Max(0, value1.Y));

                    var pNew0 = obj0.Evaluate(value0);
                    var pNew1 = obj1.Evaluate(value1);

                    var newDist = Vector3.Distance(pNew0, pNew1);
                    if (newDist > dist)
                    {
                        currAlpha /= 2;
                        currAlpha  = Math.Max(currAlpha, 0.0001f);
                    }
                    else
                    {
                        currAlpha *= 2;
                        dist       = newDist;
                        p0         = pNew0;
                        p1         = pNew1;
                    }
                }
                catch (Exception e)
                {
                    return(null);
                }
            }

            return(MyFriendNewton(obj0, obj1, value0, value1, precision));
        }
Пример #5
0
        public static Vector4 GetF(IIntersect obj0, IIntersect obj1, Vector2 uv0, Vector2 uv1, Vector2 uvNew0, Vector2 uvNew1, float alpha)
        {
            var P0 = obj0.Evaluate(uv0);
            var Q  = obj1.Evaluate(uvNew1);
            var P1 = obj0.Evaluate(uvNew0);

            var dU0 = obj0.EvaluateDU(uv0);
            var dV0 = obj0.EvaluateDV(uv0);
            var dU1 = obj1.EvaluateDU(uv1);
            var dV1 = obj1.EvaluateDV(uv1);

            var normalT = GetTNormal(dU0, dU1, dV0, dV1);
            var d       = alpha * 10;

            return(new Vector4(P1 - Q, Vector3.Dot(P1 - P0, normalT) - d));
        }
Пример #6
0
        private static List <Vector2> GetGradient(IIntersect obj0, IIntersect obj1, Vector2 point0, Vector2 point1)
        {
            var eval0 = obj0.Evaluate(point0);
            var eval1 = obj1.Evaluate(point1);

            var diff = eval0 - eval1;

            var eval0u = obj0.EvaluateDU(point0).Normalized();
            var eval0v = obj0.EvaluateDV(point0).Normalized();

            var eval1u = obj1.EvaluateDU(point1).Normalized();
            var eval1v = obj1.EvaluateDV(point1).Normalized();

            var grad0 = new Vector2(Vector3.Dot(diff, eval0u), Vector3.Dot(diff, eval0v));
            var grad1 = new Vector2(Vector3.Dot(-diff, eval1u), Vector3.Dot(-diff, eval1v));

            return(new List <Vector2>()
            {
                grad0, grad1
            });
        }
Пример #7
0
 public override IAutomat Intersect(IIntersect A) => ProductDea(this, (DFA)A, eProductDeaMode.Intersect);
Пример #8
0
 public GeometricPrimitive(IIntersect shape, IShading mat)
 {
     Shape    = shape;
     Material = mat;
 }
Пример #9
0
        private static UpdateUVStruct UpdateUV(IIntersect obj, Vector2 uv, Vector2 uvDiff, bool backed)
        {
            var backThisTime = false;
            var end          = false;

            float _uNew = uv.X - uvDiff.X;
            float _vNew = uv.Y - uvDiff.Y;

            if (_uNew < 0)
            {
                if (obj.WrappedU)
                {
                    _uNew = 1;
                }
                else
                {
                    _uNew = 0;
                    if (backed)
                    {
                        end = true;
                    }
                    else
                    {
                        backThisTime = true;
                    }
                }
            }
            else if (_uNew > 1)
            {
                if (obj.WrappedU)
                {
                    _uNew = 0;
                }
                else
                {
                    _uNew = 1;
                    if (backed)
                    {
                        end = true;
                    }
                    else
                    {
                        backThisTime = true;
                    }
                }
            }

            if (_vNew > 1)
            {
                if (obj.WrappedV)
                {
                    _vNew = 0;
                }
                else
                {
                    _vNew = 1;
                    if (backed)
                    {
                        end = true;
                    }
                    else
                    {
                        backThisTime = true;
                    }
                }
            }
            else if (_vNew < 0)
            {
                if (obj.WrappedV)
                {
                    _vNew = 1;
                }
                else
                {
                    _vNew = 0;
                    if (backed)
                    {
                        end = true;
                    }
                    else
                    {
                        backThisTime = true;
                    }
                }
            }

            return(new UpdateUVStruct()
            {
                UV = new Vector2(_uNew, _vNew),
                End = end,
                Back = backThisTime,
            });
        }
Пример #10
0
        private static IntersectionCurve MyFriendNewton(IIntersect obj0, IIntersect obj1, Vector2 uv0, Vector2 uv1, float precision)
        {
            var newtonAlpha = _newtonStartAlpha;

            var uvStart0 = uv0;
            var uvStart1 = uv1;
            var uvPrev0  = uvStart0;
            var uvPrev1  = uvStart1;

            var backed   = false;
            var finished = false;

            var pStart           = obj0.Evaluate(uvStart0);
            var countForCylinder = 0;
            var loops            = 0;

            var pointsList = new List <Vector3>();
            var uvList0    = new List <Vector2>();
            var uvList1    = new List <Vector2>();

            pointsList.Add(obj0.Evaluate(uv0));
            uvList0.Add(uv0);
            uvList1.Add(uv1);

            while (!finished)
            {
                var currAlpha  = newtonAlpha;
                int innerLoops = 0;
                while (true)
                {
                    var betterPoint = GetNewtonIterationPoint(obj0, obj1, uvPrev0, uvPrev1, uv0, uv1, currAlpha);

                    var uvDiff0 = new Vector2(betterPoint.X, betterPoint.Y);
                    var ufDivv1 = new Vector2(betterPoint.Z, betterPoint.W);

                    var upd0 = UpdateUV(obj0, uv0, uvDiff0, backed);
                    var upd1 = UpdateUV(obj1, uv1, ufDivv1, backed);
                    uv0 = upd0.UV;
                    uv1 = upd1.UV;

                    if (upd0.End || upd1.End)
                    {
                        finished = true;
                        break;
                    }

                    if (upd0.Back || upd1.Back)
                    {
                        pointsList.Reverse();
                        uvList0.Reverse();
                        uvList1.Reverse();

                        uv0 = uvStart0;
                        uv1 = uvStart1;

                        uvPrev0 = uvStart0;
                        uvPrev1 = uvStart1;

                        newtonAlpha = -_newtonStartAlpha;

                        countForCylinder = 5;
                        backed           = true;
                        currAlpha        = newtonAlpha;
                        break;
                    }

                    var ev0 = obj0.Evaluate(uv0);
                    var ev1 = obj1.Evaluate(uv1);
                    var dst = Vector3.Distance(ev0, ev1);
                    if (precision > dst)
                    {
                        break;
                    }

                    if (++innerLoops > 30)
                    {
                        return(null);
                    }
                }

                uvPrev0 = uv0;
                uvPrev1 = uv1;

                var p1   = obj0.Evaluate(uv0);
                var p2   = obj1.Evaluate(uv1);
                var dist = Vector3.Distance(p2, p1);
                if (_alphaEpsilon < Vector3.Distance(p2, p1))
                {
                    currAlpha /= 2;
                }

                pointsList.Add(obj0.Evaluate(uv0));
                uvList0.Add(uv0);
                uvList1.Add(uv1);

                if (loops > 1000 || _finalEpsilon > Vector3.Distance(pStart, p1) && countForCylinder > 10)
                {
                    break;
                }

                countForCylinder++;
                loops++;
            }

            return(new IntersectionCurve(pointsList, uvList0, uvList1));
        }
Пример #11
0
 public abstract IAutomat Intersect(IIntersect a);
Пример #12
0
 public override IAutomat Intersect(IIntersect A) => throw new System.NotImplementedException();