Sqrt() public static method

public static Sqrt ( float f ) : float
f float
return float
コード例 #1
0
 public static float InOut(float k)
 {
     if ((k *= 2f) < 1f)
     {
         return(-0.5f * (Mathf.Sqrt(1f - k * k) - 1));
     }
     return(0.5f * (Mathf.Sqrt(1f - (k -= 2f) * k) + 1f));
 }
コード例 #2
0
ファイル: Easings.cs プロジェクト: Salwan/1gam_feb18_music
 /// <summary>
 /// Modeled after the piecewise circular function
 /// y = (1/2)(1 - Math.Sqrt(1 - 4x^2))           ; [0, 0.5)
 /// y = (1/2)(Math.Sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
 /// </summary>
 static public float CircularEaseInOut(float p)
 {
     if (p < 0.5f)
     {
         return(0.5f * (1.0f - Math.Sqrt(1.0f - 4.0f * (p * p))));
     }
     else
     {
         return(0.5f * (Math.Sqrt(-((2.0f * p) - 3.0f) * ((2.0f * p) - 1.0f)) + 1.0f));
     }
 }
コード例 #3
0
 /// <summary>
 /// Modeled after the piecewise circular function
 /// y = (1/2)(1 - Math.Sqrt(1 - 4x^2))           ; [0, 0.5)
 /// y = (1/2)(Math.Sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
 /// </summary>
 static public float CircularEaseInOut(float p)
 {
     if (p < 0.5f)
     {
         return(0.5f * (1 - Math.Sqrt(1 - 4 * (p * p))));
     }
     else
     {
         return(0.5f * (Math.Sqrt(-((2 * p) - 3) * ((2 * p) - 1)) + 1));
     }
 }
コード例 #4
0
        /** Evaluate gradient and value of the cost function at velocity p */
        Vector2 EvaluateGradient(VOBuffer vos, Vector2 p, out float value)
        {
            Vector2 gradient = Vector2.zero;

            value = 0;

            // Avoid other agents
            for (int i = 0; i < vos.length; i++)
            {
                float w;
                var   grad = vos.buffer[i].ScaledGradient(p, out w);
                if (w > value)
                {
                    value    = w;
                    gradient = grad;
                }
            }

            // Move closer to the desired velocity
            var dirToDesiredVelocity  = desiredVelocity - p;
            var distToDesiredVelocity = dirToDesiredVelocity.magnitude;

            if (distToDesiredVelocity > 0.0001f)
            {
                gradient += dirToDesiredVelocity * (DesiredVelocityWeight / distToDesiredVelocity);
                value    += distToDesiredVelocity * DesiredVelocityWeight;
            }

            // Prefer speeds lower or equal to the desired speed
            // and avoid speeds greater than the max speed
            var sqrSpeed = p.sqrMagnitude;

            if (sqrSpeed > desiredSpeed * desiredSpeed)
            {
                var speed = Mathf.Sqrt(sqrSpeed);

                if (speed > maxSpeed)
                {
                    const float MaxSpeedWeight = 3;
                    value    += MaxSpeedWeight * (speed - maxSpeed);
                    gradient -= MaxSpeedWeight * (p / speed);
                }

                // Scale needs to be strictly greater than DesiredVelocityWeight
                // otherwise the agent will not prefer the desired speed over
                // the maximum speed
                float scale = 2 * DesiredVelocityWeight;
                value    += scale * (speed - desiredSpeed);
                gradient -= scale * (p / speed);
            }

            return(gradient);
        }
コード例 #5
0
    public static float Circ_EaseOut(float a, float b, float t)
    {
        if (t > 1.0F)
        {
            t = 1.0F;
        }
        if (t < 0.0F)
        {
            t = 0.0F;
        }

        float x = (float)Math.Sqrt(1 - (t - 1f) * (t - 1f)); // F(x) =  sqrt(1 - (x-1)*(x-1)) for x in (0,1)

        return(a + x * (b - a));
    }
コード例 #6
0
        private static void Reconstruct(byte[] components, out float a, out float b, out float c, out float r, bool shouldNegate)
        {
            a = Read7BitFloat(components[0]);
            b = Read7BitFloat(components[1]);
            c = Read7BitFloat(components[2]);
            //Reconstruct
            r = Mathf.Sqrt(1 - (a * a) - (b * b) - (c * c));

            if (shouldNegate)
            {
                a = -a;
                b = -b;
                c = -c;
            }
        }
コード例 #7
0
    public static float Circ_EaseIn(float a, float b, float t)
    {
        if (t > 1.0F)
        {
            t = 1.0F;
        }
        if (t < 0.0F)
        {
            t = 0.0F;
        }

        float x = -((float)Math.Sqrt(1 - t * t) - 1.0F); // F(x) =  -(sqrt(1 - x*x) - 1) for x in (0,1)

        return(a + x * (b - a));
    }
コード例 #8
0
        /** Returns points in a spiral centered around the origin with a minimum clearance from other points.
         * The points are laid out on the involute of a circle
         * \see http://en.wikipedia.org/wiki/Involute
         * Which has some nice properties.
         * All points are separated by \a clearance world units.
         * This method is O(n), yes if you read the code you will see a binary search, but that binary search
         * has an upper bound on the number of steps, so it does not yield a log factor.
         *
         * \note Consider recycling the list after usage to reduce allocations.
         * \see Pathfinding.Util.ListPool
         */
        public static List <Vector3> GetSpiralPoints(int count, float clearance)
        {
            List <Vector3> pts = ListPool <Vector3> .Claim(count);

            // The radius of the smaller circle used for generating the involute of a circle
            // Calculated from the separation distance between the turns
            float a = clearance / (2 * Mathf.PI);
            float t = 0;


            pts.Add(InvoluteOfCircle(a, t));

            for (int i = 0; i < count; i++)
            {
                Vector3 prev = pts[pts.Count - 1];

                // d = -t0/2 + sqrt( t0^2/4 + 2d/a )
                // Minimum angle (radians) which would create an arc distance greater than clearance
                float d = -t / 2 + Mathf.Sqrt(t * t / 4 + 2 * clearance / a);

                // Binary search for separating this point and the previous one
                float mn = t + d;
                float mx = t + 2 * d;
                while (mx - mn > 0.01f)
                {
                    float   mid = (mn + mx) / 2;
                    Vector3 p   = InvoluteOfCircle(a, mid);
                    if ((p - prev).sqrMagnitude < clearance * clearance)
                    {
                        mn = mid;
                    }
                    else
                    {
                        mx = mid;
                    }
                }

                pts.Add(InvoluteOfCircle(a, mx));
                t = mx;
            }

            return(pts);
        }
コード例 #9
0
        void Tick()
        {
            if (Event.current.type == EventType.Repaint)
            {
                float deltaTime = Time.realtimeSinceStartup - lastUpdate;

                // Right at the start of a transition the deltaTime will
                // not be reliable, so use a very small value instead
                // until the next repaint
                if (value == 0f || value == 1f)
                {
                    deltaTime = 0.001f;
                }
                deltaTime = Mathf.Clamp(deltaTime, 0.00001F, 0.1F);

                // Larger regions fade slightly slower
                deltaTime /= Mathf.Sqrt(Mathf.Max(lastRect.height, 100));

                lastUpdate = Time.realtimeSinceStartup;


                float targetValue = open ? 1F : 0F;
                if (!Mathf.Approximately(targetValue, value))
                {
                    value += deltaTime * animationSpeed * Mathf.Sign(targetValue - value);
                    value  = Mathf.Clamp01(value);
                    editor.Repaint();

                    if (!fancyEffects)
                    {
                        value = targetValue;
                    }
                }
                else
                {
                    value = targetValue;
                }
            }
        }
コード例 #10
0
ファイル: Draw.cs プロジェクト: isoundy000/ETGame
        public void CircleXZ(Vector3 center, float radius, Color color, float startAngle = 0f, float endAngle = 2 *Mathf.PI)
        {
            int steps = 40;

#if UNITY_EDITOR
            if (gizmos)
            {
                steps = (int)Mathf.Clamp(Mathf.Sqrt(radius / UnityEditor.HandleUtility.GetHandleSize((UnityEngine.Gizmos.matrix * matrix).MultiplyPoint3x4(center))) * 25, 4, 40);
            }
#endif
            while (startAngle > endAngle)
            {
                startAngle -= 2 * Mathf.PI;
            }

            Vector3 prev = new Vector3(Mathf.Cos(startAngle) * radius, 0, Mathf.Sin(startAngle) * radius);
            for (int i = 0; i <= steps; i++)
            {
                Vector3 c = new Vector3(Mathf.Cos(Mathf.Lerp(startAngle, endAngle, i / (float)steps)) * radius, 0, Mathf.Sin(Mathf.Lerp(startAngle, endAngle, i / (float)steps)) * radius);
                Line(center + prev, center + c, color);
                prev = c;
            }
        }
コード例 #11
0
    public static float Circ_EaseInOut(float a, float b, float t)
    {
        if (t > 1.0F)
        {
            t = 1.0F;
        }
        if (t < 0.0F)
        {
            t = 0.0F;
        }

        float x = t;

        if (t <= 0.5f)
        {
            x = -0.5F * ((float)Math.Sqrt(1.0F - t * t * 4) - 1.0F);  // x <= 0,5: F(x) = -0.5*(sqrt(1 - x*x*4) - 1) in (0, 0.5)
        }
        else
        {
            x = (float)Math.Sqrt(-(t - 0.5F) * (t - 1.5F)) + 0.5F;  // x > 0,5: F(x) = 0.5*(sqrt(1 - (x-1)*(x-1)*4) +1 ) === (sqrt(-(x-0.5)*(x-1.5)) +0.5) in (0.5, 1)
        }
        return(a + x * (b - a));
    }
コード例 #12
0
 /// <summary>
 /// Modeled after shifted quadrant IV of unit circle
 /// </summary>
 static public float CircularEaseIn(float p)
 {
     return(1 - Math.Sqrt(1 - (p * p)));
 }
コード例 #13
0
    void Update()
    {
        Vec3 pos;
        /* Cosine of the angle on the X-Z ("horizontal") plane */
        float xCosTeta;
        /* Sine of the angle on the Z-Y ("vertical") plane */
        float ySinPhi;

        if (this.player == null)
        {
            GO pl = null;
            this.rootEvent <GetPlayer>((x, y) => x.Get(out pl));
            if (pl != null)
            {
                this.player = pl.transform;
            }
            return;
        }

        if (!Input.GetMouseCameraEnabled())
        {
            /* Try to manipulate the camera using a gamepad */
            xCosTeta           = Global.camX * -1.0f * Input.GetCameraX();
            ySinPhi            = Global.camY * Input.GetCameraY();
            this.wasUsingMouse = false;
        }
        else
        {
            if (this.wasUsingMouse)
            {
                /* Move the camera, using a 50px (?) circle around the mouse */
                Vec3 mouseDelta = Input.GetMousePosition() - this.mouse;
                xCosTeta = Global.camX * -1.0f * mouseDelta.x * 0.02f;
                ySinPhi  = Global.camY * -1.0f * mouseDelta.y * 0.02f;
                ySinPhi  = Math.Clamp(ySinPhi, -1.0f, 1.0f);
            }
            else
            {
                /* Use the current position as the mouse's origin */
                this.mouse         = Input.GetMousePosition();
                this.wasUsingMouse = true;
                xCosTeta           = 0.0f;
                ySinPhi            = 0.0f;
            }
        }
        xCosTeta = Math.Clamp(xCosTeta, -0.8f, 0.8f);

        float dist = Math.Sqrt(xCosTeta * xCosTeta + ySinPhi * ySinPhi);

        if (!this.wasUsingMouse && dist < 0.5f)
        {
            pos = new Vec3(this.baseDX, this.baseDY, this.baseDZ);
        }
        else
        {
            float zSinTeta = -1.0f * Math.Sqrt(1.0f - xCosTeta * xCosTeta);
            float zCosPhi  = -1.0f * Math.Sqrt(1.0f - ySinPhi * ySinPhi);

            pos = new Vec3(xCosTeta, ySinPhi, (zSinTeta + zCosPhi) * 0.5f);
        }
        pos          = pos.normalized * this.distance;
        this.lastPos = 0.75f * this.lastPos + pos * 0.25f;

        this.cam.position = this.player.position + this.lastPos;
        this.cam.LookAt(this.player);
    }
コード例 #14
0
        /** Will calculate a number of points around \a center which are on the graph and are separated by \a clearance from each other.
         * The maximum distance from \a center to any point will be \a radius.
         * Points will first be tried to be laid out as \a previousPoints and if that fails, random points will be selected.
         * This is great if you want to pick a number of target points for group movement. If you pass all current agent points from e.g the group's average position
         * this method will return target points so that the units move very little within the group, this is often aesthetically pleasing and reduces jitter if using
         * some kind of local avoidance.
         *
         * \param center The point to generate points around
         * \param g The graph to use for linecasting. If you are only using one graph, you can get this by AstarPath.active.graphs[0] as IRaycastableGraph.
         * Note that not all graphs are raycastable, recast, navmesh and grid graphs are raycastable. On recast and navmesh it works the best.
         * \param previousPoints The points to use for reference. Note that these should not be in world space. They are treated as relative to \a center.
         *      The new points will overwrite the existing points in the list. The result will be in world space, not relative to \a center.
         * \param radius The final points will be at most this distance from \a center.
         * \param clearanceRadius The points will if possible be at least this distance from each other.
         *
         * \todo Write unit tests
         */
        public static void GetPointsAroundPoint(Vector3 center, IRaycastableGraph g, List <Vector3> previousPoints, float radius, float clearanceRadius)
        {
            if (g == null)
            {
                throw new System.ArgumentNullException("g");
            }

            var graph = g as NavGraph;

            if (graph == null)
            {
                throw new System.ArgumentException("g is not a NavGraph");
            }

            NNInfoInternal nn = graph.GetNearestForce(center, NNConstraint.Default);

            center = nn.clampedPosition;

            if (nn.node == null)
            {
                // No valid point to start from
                return;
            }


            // Make sure the enclosing circle has a radius which can pack circles with packing density 0.5
            radius           = Mathf.Max(radius, 1.4142f * clearanceRadius * Mathf.Sqrt(previousPoints.Count)); //Mathf.Sqrt(previousPoints.Count*clearanceRadius*2));
            clearanceRadius *= clearanceRadius;

            for (int i = 0; i < previousPoints.Count; i++)
            {
                Vector3 dir  = previousPoints[i];
                float   magn = dir.magnitude;

                if (magn > 0)
                {
                    dir /= magn;
                }

                float newMagn = radius;                //magn > radius ? radius : magn;
                dir *= newMagn;

                GraphHitInfo hit;

                int tests = 0;
                while (true)
                {
                    Vector3 pt = center + dir;

                    if (g.Linecast(center, pt, nn.node, out hit))
                    {
                        if (hit.point == PF.Vector3.zero)
                        {
                            // Oops, linecast actually failed completely
                            // try again unless we have tried lots of times
                            // then we just continue anyway
                            tests++;
                            if (tests > 8)
                            {
                                previousPoints[i] = pt;
                                break;
                            }
                        }
                        else
                        {
                            pt = hit.point;
                        }
                    }

                    bool worked = false;

                    for (float q = 0.1f; q <= 1.0f; q += 0.05f)
                    {
                        Vector3 qt = Vector3.Lerp(center, pt, q);
                        worked = true;
                        for (int j = 0; j < i; j++)
                        {
                            if ((previousPoints[j] - qt).sqrMagnitude < clearanceRadius)
                            {
                                worked = false;
                                break;
                            }
                        }

                        // Abort after 8 tests or when we have found a valid point
                        if (worked || tests > 8)
                        {
                            worked            = true;
                            previousPoints[i] = qt;
                            break;
                        }
                    }

                    // Break out of nested loop
                    if (worked)
                    {
                        break;
                    }

                    // If we could not find a valid point, reduce the clearance radius slightly to improve
                    // the chances next time
                    clearanceRadius *= 0.9f;
                    // This will pick points in 2D closer to the edge of the circle with a higher probability
                    dir   = Random.onUnitSphere * Mathf.Lerp(newMagn, radius, tests / 5);
                    dir.y = 0;
                    tests++;
                }
            }
        }
コード例 #15
0
        RasterizationMesh RasterizeCapsuleCollider(float radius, float height, Bounds bounds, Matrix4x4 localToWorldMatrix)
        {
            // Calculate the number of rows to use
            // grows as sqrt(x) to the radius of the sphere/capsule which I have found works quite well
            int rows = Mathf.Max(4, Mathf.RoundToInt(colliderRasterizeDetail * Mathf.Sqrt(localToWorldMatrix.MultiplyVector(Vector3.one).magnitude)));

            if (rows > 100)
            {
                Debug.LogWarning("Very large detail for some collider meshes. Consider decreasing Collider Rasterize Detail (RecastGraph)");
            }

            int cols = rows;

            Vector3[] verts;
            int[]     trisArr;

            // Check if we have already calculated a similar capsule
            CapsuleCache cached = null;

            for (int i = 0; i < capsuleCache.Count; i++)
            {
                CapsuleCache c = capsuleCache[i];
                if (c.rows == rows && Mathf.Approximately(c.height, height))
                {
                    cached = c;
                }
            }

            if (cached == null)
            {
                // Generate a sphere/capsule mesh

                verts = new Vector3[(rows) * cols + 2];

                var tris = new List <int>();
                verts[verts.Length - 1] = Vector3.up;

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < cols; c++)
                    {
                        verts[c + r * cols] = new Vector3(Mathf.Cos(c * Mathf.PI * 2 / cols) * Mathf.Sin((r * Mathf.PI / (rows - 1))), Mathf.Cos((r * Mathf.PI / (rows - 1))) + (r < rows / 2 ? height : -height), Mathf.Sin(c * Mathf.PI * 2 / cols) * Mathf.Sin((r * Mathf.PI / (rows - 1))));
                    }
                }

                verts[verts.Length - 2] = Vector3.down;

                for (int i = 0, j = cols - 1; i < cols; j = i++)
                {
                    tris.Add(verts.Length - 1);
                    tris.Add(0 * cols + j);
                    tris.Add(0 * cols + i);
                }

                for (int r = 1; r < rows; r++)
                {
                    for (int i = 0, j = cols - 1; i < cols; j = i++)
                    {
                        tris.Add(r * cols + i);
                        tris.Add(r * cols + j);
                        tris.Add((r - 1) * cols + i);

                        tris.Add((r - 1) * cols + j);
                        tris.Add((r - 1) * cols + i);
                        tris.Add(r * cols + j);
                    }
                }

                for (int i = 0, j = cols - 1; i < cols; j = i++)
                {
                    tris.Add(verts.Length - 2);
                    tris.Add((rows - 1) * cols + j);
                    tris.Add((rows - 1) * cols + i);
                }

                // Add calculated mesh to the cache
                cached        = new CapsuleCache();
                cached.rows   = rows;
                cached.height = height;
                cached.verts  = verts;
                cached.tris   = tris.ToArray();
                capsuleCache.Add(cached);
            }

            // Read from cache
            verts   = cached.verts;
            trisArr = cached.tris;

            return(new RasterizationMesh(verts, trisArr, bounds, localToWorldMatrix));
        }
コード例 #16
0
 private static float GuassianFunc(float x) => Mathf.Exp((-(x * x)) / 2F) / Mathf.Sqrt(2F * Mathf.PI);
コード例 #17
0
        /** Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not */
        protected override void MovementUpdateInternal(float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation)
        {
            float currentAcceleration = maxAcceleration;

            // If negative, calculate the acceleration from the max speed
            if (currentAcceleration < 0)
            {
                currentAcceleration *= -maxSpeed;
            }

            if (updatePosition)
            {
                // Get our current position. We read from transform.position as few times as possible as it is relatively slow
                // (at least compared to a local variable)
                simulatedPosition = tr.position;
            }
            if (updateRotation)
            {
                simulatedRotation = tr.rotation;
            }

            var currentPosition = simulatedPosition;

            // Update which point we are moving towards
            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            var dir = movementPlane.ToPlane(steeringTarget - currentPosition);

            // Calculate the distance to the end of the path
            float distanceToEnd = dir.magnitude + Mathf.Max(0, interpolator.remainingDistance);

            // Check if we have reached the target
            var prevTargetReached = reachedEndOfPath;

            reachedEndOfPath = distanceToEnd <= endReachedDistance && interpolator.valid;
            if (!prevTargetReached && reachedEndOfPath)
            {
                OnTargetReached();
            }
            float slowdown;

            // Normalized direction of where the agent is looking
            var forwards = movementPlane.ToPlane(simulatedRotation * (rotationIn2D ? Vector3.up : Vector3.forward));

            // Check if we have a valid path to follow and some other script has not stopped the character
            if (interpolator.valid && !isStopped)
            {
                // How fast to move depending on the distance to the destination.
                // Move slower as the character gets closer to the destination.
                // This is always a value between 0 and 1.
                slowdown = distanceToEnd < slowdownDistance?Mathf.Sqrt(distanceToEnd / slowdownDistance) : 1;

                if (reachedEndOfPath && whenCloseToDestination == CloseToDestinationMode.Stop)
                {
                    // Slow down as quickly as possible
                    velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
                }
                else
                {
                    velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir.ToUnityV2(), dir.normalized * maxSpeed, velocity2D, currentAcceleration, rotationSpeed, maxSpeed, forwards) * deltaTime;
                }
            }
            else
            {
                slowdown = 1;
                // Slow down as quickly as possible
                velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
            }

            velocity2D = MovementUtilities.ClampVelocity(velocity2D, maxSpeed, slowdown, slowWhenNotFacingTarget, forwards.ToUnityV2());

            ApplyGravity(deltaTime);

            if (rvoController != null && rvoController.enabled)
            {
                // Send a message to the RVOController that we want to move
                // with this velocity. In the next simulation step, this
                // velocity will be processed and it will be fed back to the
                // rvo controller and finally it will be used by this script
                // when calling the CalculateMovementDelta method below

                // Make sure that we don't move further than to the end point
                // of the path. If the RVO simulation FPS is low and we did
                // not do this, the agent might overshoot the target a lot.
                var rvoTarget = currentPosition.ToPFV3() + movementPlane.ToWorld(Vector2.ClampMagnitude(velocity2D, distanceToEnd), 0f);
                rvoController.SetTarget(rvoTarget, velocity2D.magnitude, maxSpeed);
            }

            // Set how much the agent wants to move during this frame
            var delta2D = lastDeltaPosition = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);

            nextPosition = currentPosition + movementPlane.ToWorld(delta2D.ToPFV2(), verticalVelocity * lastDeltaTime).ToUnityV3();
            CalculateNextRotation(slowdown, out nextRotation);
        }
コード例 #18
0
 public static float Out(float k)
 {
     return(Mathf.Sqrt(1f - ((k -= 1f) * k)));
 }
コード例 #19
0
 public static float In(float k)
 {
     return(1f - Mathf.Sqrt(1f - k * k));
 }
コード例 #20
0
 /// <summary>
 /// Modeled after shifted quadrant II of unit circle
 /// </summary>
 static public float CircularEaseOut(float p)
 {
     return(Math.Sqrt((2 - p) * p));
 }
コード例 #21
0
ファイル: AutoPupil.cs プロジェクト: lfe999/VamAutoPupil
        void Update()
        {
            if (Detector.targetTexture != null)
            {
                // get a copy of the pixels into a Texture2D

                // the script assumes the 2d and rendertexture are the same size if ever minds are changed this is a reminder
                // if (cameraTexture2d.width != cameraRenderTexture.width || cameraTexture2d.height != cameraRenderTexture.height)
                // {
                //     cameraTexture2d.Resize(cameraRenderTexture.width, cameraRenderTexture.height);
                // }

                var previous = RenderTexture.active;
                RenderTexture.active = cameraRenderTexture;
                cameraTexture2d.ReadPixels(new Rect(0, 0, cameraRenderTexture.width, cameraRenderTexture.height), 0, 0);
                cameraTexture2d.Apply(false, false);
                RenderTexture.active = previous;

                // average the colors in the image
                var colors = cameraTexture2d.GetPixels32();
                var total = colors.Length;
                var r = 0; var g = 0; var b = 0;
                for (int i = 0; i < total; i++)
                {
                    r += colors[i].r;
                    g += colors[i].g;
                    b += colors[i].b;
                }
                var color = new Color(r / total, g / total, b / total);
                // https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
                var brightness = Math.Sqrt(
                    color.r * color.r * .299f +
                    color.g * color.g * .587f +
                    color.b * color.b * .114f
                    ) / 255;
                if (brightness > 1)
                {
                    brightness = 1;
                }
                else if (brightness < 0)
                {
                    brightness = 0;
                }

                // set our public properties now
                DetectedColor      = color;
                DetectedBrightness = brightness;
#if LFE_DEBUG
                SuperController.LogMessage($"color = {color} brightness = {brightness}");
#endif

                // stop capturing the screen
                Detector.targetTexture = null;
#if !LFE_DEBUG
                if (PollFrequency > 0)
                {
                    Detector.enabled = false;
                }
#endif
            }

            pollCountdown -= Time.deltaTime;
            if (pollCountdown > 0)
            {
                // wait
                return;
            }
            else
            {
                // schedule the next update to capture the screen
#if !LFE_DEBUG
                if (PollFrequency > 0)
                {
                    Detector.enabled = true;
                }
#endif
                pollCountdown          = PollFrequency;
                Detector.targetTexture = cameraRenderTexture;
            }
        }
コード例 #22
0
 public static float Magnitude(Vector4 a)
 {
     return(Mathf.Sqrt(Vector4.Dot(a, a)));
 }
コード例 #23
0
            /** Creates a VO for avoiding another agent.
             * Note that the segment is directed, the agent will want to be on the left side of the segment.
             */
            public static VO SegmentObstacle(Vector2 segmentStart, Vector2 segmentEnd, Vector2 offset, float radius, float inverseDt, float inverseDeltaTime)
            {
                var vo = new VO();

                // Adjusted so that a parameter weightFactor of 1 will be the default ("natural") weight factor
                vo.weightFactor = 1;
                // Just higher than anything else
                vo.weightBonus = Mathf.Max(radius, 1) * 40;

                var closestOnSegment = VectorMath.ClosestPointOnSegment(segmentStart.ToPFV2(), segmentEnd.ToPFV2(), Vector2.zero.ToPFV2());

                // Collision?
                if (closestOnSegment.magnitude <= radius)
                {
                    vo.colliding = true;

                    vo.line1  = closestOnSegment.normalized.ToUnityV3() * (closestOnSegment.magnitude - radius) * 0.3f * inverseDeltaTime;
                    vo.dir1   = new Vector2(vo.line1.y, -vo.line1.x).normalized;
                    vo.line1 += offset;

                    vo.cutoffDir  = Vector2.zero;
                    vo.cutoffLine = Vector2.zero;
                    vo.dir2       = Vector2.zero;
                    vo.line2      = Vector2.zero;
                    vo.radius     = 0;

                    vo.segmentStart = Vector2.zero;
                    vo.segmentEnd   = Vector2.zero;
                    vo.segment      = false;
                }
                else
                {
                    vo.colliding = false;

                    segmentStart *= inverseDt;
                    segmentEnd   *= inverseDt;
                    radius       *= inverseDt;

                    var cutoffTangent = (segmentEnd - segmentStart).normalized;
                    vo.cutoffDir   = cutoffTangent;
                    vo.cutoffLine  = segmentStart + new Vector2(-cutoffTangent.y, cutoffTangent.x) * radius;
                    vo.cutoffLine += offset;

                    // See documentation for details
                    // The call to Max is just to prevent floating point errors causing NaNs to appear
                    var startSqrMagnitude = segmentStart.sqrMagnitude;
                    var normal1           = -VectorMath.ComplexMultiply(segmentStart, new Vector2(radius, Mathf.Sqrt(Mathf.Max(0, startSqrMagnitude - radius * radius)))) / startSqrMagnitude;
                    var endSqrMagnitude   = segmentEnd.sqrMagnitude;
                    var normal2           = -VectorMath.ComplexMultiply(segmentEnd, new Vector2(radius, -Mathf.Sqrt(Mathf.Max(0, endSqrMagnitude - radius * radius)))) / endSqrMagnitude;

                    vo.line1 = segmentStart + normal1.ToUnityV2() * radius + offset;
                    vo.line2 = segmentEnd + normal2.ToUnityV2() * radius + offset;

                    // Note that the normals are already normalized
                    vo.dir1 = new Vector2(normal1.y, -normal1.x);
                    vo.dir2 = new Vector2(normal2.y, -normal2.x);

                    vo.segmentStart = segmentStart;
                    vo.segmentEnd   = segmentEnd;
                    vo.radius       = radius;
                    vo.segment      = true;
                }

                return(vo);
            }