Home > Net >  How to enable true object only when the object is inside the radar cone area?
How to enable true object only when the object is inside the radar cone area?

Time:11-28

I have this Image as the cone and the cone is rotating 360 degrees. I want that if one of the 3 objects at the bottom : Cube 2 , Cube 1 , Spehere are distance that they are inside the cone area then enable true the object that is inside the cone area.

The main goal is make a doppler radar and to turn on or make visible objects that are inside the cone area same idea as clouds doppler radar.

radar

this is the code that rotating the cone :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ConeRotation : MonoBehaviour
{
    public float rotSpeed = 250;
    public float damping = 10;

    private float desiredRot;
    private bool autoRotate = false;

    // Start is called before the first frame update
    void Start()
    {
        desiredRot = transform.eulerAngles.z;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            if (Input.mousePosition.x > Screen.width / 2) desiredRot -= rotSpeed * Time.deltaTime;
            else desiredRot  = rotSpeed * Time.deltaTime;
        }

        if (Input.GetMouseButton(1))
        {
            if (Input.mousePosition.x > Screen.width / 2) desiredRot -= rotSpeed * Time.deltaTime;
            else desiredRot -= rotSpeed * Time.deltaTime;
        }

        if (Input.GetMouseButtonDown(2))
        {
            autoRotate = !autoRotate;
        }

        if (autoRotate)
        {
            desiredRot  = rotSpeed * Time.deltaTime;
        }

        var desiredRotQ = Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, desiredRot);
        transform.rotation = Quaternion.Lerp(transform.rotation, desiredRotQ, Time.deltaTime * damping);
    }
}

This is how i used to do it in csharp winforms but it was using very old directx dll files maybe 15 and more years old files. and now it's hard to make it working again but this is how i used to detect clouds(points) inside the radar cone area in csharp winforms. since i don't know how to make this doppler effect in csharp now i'm trying to do it with the unity.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;

namespace Doppler
{
    class Doppler
    {
        [DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
        public static extern IntPtr MemSet(IntPtr dest, int c, int count);

        private System.Windows.Forms.Timer timer1;
        private Stream mymem;
        private Bitmap ConvertedBmp;
        private Device D3Ddev = null;
        private PresentParameters D3Dpp = null;
        private DisplayMode DispMode;
        private Sprite D3Dsprite = null;
        private Texture backTexture = null;
        private Texture scannedCloudsTexture = null;
        private byte[] argbValuesOfTransparentTexture;
        private float distanceFromCenterPixels;
        private float distanceFromCenterKm = 200F;
        private List<Point> detectedPoints;
        private float[] angleArray, distanceArray;
        private double angleCalculation, distance;
        private Bitmap bmpnew = new Bitmap(512, 512);
        private int bytes = 2048 * 512;
        public System.Windows.Forms.PictureBox pb1;

        public void Init()
        {
            timer1 = new System.Windows.Forms.Timer();
            timer1.Interval = 10;
            timer1.Enabled = false;
            timer1.Tick  = Timer1_Tick;

            ConvertedBmp = ConvertTo24(@"D:\Downloaded Images\test.gif");
            mymem = ToStream(ConvertedBmp, ImageFormat.Bmp);

            distanceFromCenterPixels = (float)(/*183d*/ ((double)200 / 1.09289617486) * (double)distanceFromCenterKm / 200d);
            argbValuesOfTransparentTexture = new byte[bytes];

            InitializeDirectX(pb1);

            FindPoints();
            //initialize angleArray
            angleArray = new float[detectedPoints.Count];
            distanceArray = new float[detectedPoints.Count];

            for (int i = 0; i < detectedPoints.Count; i  )
            {
                CalculateAngleAndDistance(detectedPoints[i].X, detectedPoints[i].Y, out angleCalculation, out distance);

                angleArray[i] = (float)angleCalculation;
                distanceArray[i] = (float)distance;
            }
            timer1.Enabled = true;
        }

        static float angleF_ = 0.0F;
        private void Timer1_Tick(object sender, EventArgs e)
        {
            if (angleF_ > 360F)
            {
                angleF_ -= 360F;
            }

            ReturnTexture(scannedCloudsTexture, detectedPoints, angleArray, angleF_, bmpnew);

            DisplayOnScreen(angleF_);

            // To change direction to change  = to -=
            // To change speed to raise the value 1.0d 
            angleF_  = 1.0F;
        }

        private Bitmap ConvertTo24(string inputFileName)
        {
            Stopwatch sw = new Stopwatch();
            sw = Stopwatch.StartNew();

            Bitmap bmpIn = (Bitmap)Bitmap.FromFile(inputFileName);

            Bitmap converted = new Bitmap(bmpIn.Width, bmpIn.Height, PixelFormat.Format24bppRgb);
            using (Graphics g = Graphics.FromImage(converted))
            {
                // Prevent DPI conversion
                g.PageUnit = GraphicsUnit.Pixel;
                // Draw the image
                g.DrawImageUnscaled(bmpIn, 0, 0);
            }
            //converted.Save(outputFileName, ImageFormat.Bmp);
            sw.Stop();
            return converted;
        }

        public static Stream ToStream(Image image, ImageFormat formaw)
        {
            var stream = new MemoryStream();
            image.Save(stream, formaw);
            stream.Position = 0;
            return stream;
        }

        public Boolean InitializeDirectX(System.Windows.Forms.PictureBox pb1)
        {

            DispMode = Manager.Adapters[Manager.Adapters.Default.Adapter].CurrentDisplayMode;
            D3Dpp = new PresentParameters();
            D3Dpp.BackBufferFormat = DispMode.Format;
            D3Dpp.PresentFlag = PresentFlag.LockableBackBuffer;

            D3Dpp.SwapEffect = SwapEffect.Discard;
            D3Dpp.PresentationInterval = PresentInterval.One; //wait for vertical sync. Synchronizes the painting with
                                                              //monitor refresh rate for smoooth animation
            D3Dpp.Windowed = true; //the application has borders

            try
            {
                D3Ddev = new Device(Manager.Adapters.Default.Adapter, DeviceType.Hardware, pb1.Handle,
                                                                           CreateFlags.SoftwareVertexProcessing, D3Dpp);
                //D3Ddev.VertexFormat = CustomVertex.PositionColored.Format;
                D3Ddev.RenderState.Lighting = false;
                D3Ddev.RenderState.CullMode = Cull.CounterClockwise;

                //load imagesBmp to panelTexture
                //panelTexture = Texture.FromBitmap(D3Ddev, imagesBmp, Usage.Dynamic, Pool.Default)

                backTexture = TextureLoader.FromStream(D3Ddev, mymem);




                //scannerTexture = TextureLoader.FromFile(D3Ddev, @"D:\Buttons\Radar\radar.png");
                scannedCloudsTexture = new Texture(D3Ddev, 512, 512, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);

                //sprite is used to draw the texture
                D3Dsprite = new Sprite(D3Ddev);

                return true;
            }
            catch
            {
                return false;
            }
        }

        Bitmap bmpn;
        float angle = 0;
        private void DisplayOnScreen(float angleF)
        {

            if (angle < 360)
            {
                bmpn = new Bitmap(512, 512);
                angle  ;
            }
            else
            {
                angle = 361;
            }
            Surface backbuffer;
            Brush myBrush = new SolidBrush(Color.FromArgb(110, 0, 255, 0)); //semi transparent color to draw the rotating cone 
            Graphics g;

            //clear the backbuffer with Color.FromArgb(56, 56, 56). This is the double buffer mechanism. Drawing to offscreen 
            //backbuffer and in the end flipping it to main one which is our panelContainer 
            D3Ddev.Clear(ClearFlags.Target, Color.FromArgb(56, 56, 56), 1, 0);
            D3Ddev.BeginScene();

            //Draw Sprites 
            ////////////////////////////////////////////////////// 
            D3Dsprite.Begin(SpriteFlags.AlphaBlend);

            // bitmap with clouds 
            D3Dsprite.Draw2D(backTexture, new PointF(0, 0), 0F, new PointF(0F, 0F), Color.White);
            //the part of clouds that are inside the cone 
            D3Dsprite.Draw2D(scannedCloudsTexture, new PointF(0F, 0F), 0F, new PointF(0F, 0F), Color.White);
            //rotate cone 
            //D3Dsprite.Draw2D(scannerTexture, new PointF(104.5F, 0F), angle, new PointF(256F, 255F), Color.White); 

            D3Dsprite.Flush();
            D3Dsprite.End();
            ////////////////////////////////////////////////////// 


            //Draw the cone. 
            using (backbuffer = D3Ddev.GetBackBuffer(0, 0, BackBufferType.Mono))
            {
                using (g = backbuffer.GetGraphics())
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;

                    g.FillPie(myBrush, 256F - distanceFromCenterPixels, 255F - distanceFromCenterPixels,
                    distanceFromCenterPixels * 2F, distanceFromCenterPixels * 2F, angleF - 23F, 46F);
                    if (angle <= 360)
                    {

                    }

                }
            }

            D3Ddev.EndScene();
            D3Ddev.Present(); //performs the flipping 

        }

        private void CalculateAngleAndDistance(int x, int y, out double angle, out double distance)
        {
            Double dbl = -1.0d;
            Point center = new Point(256, 255);

            distance = Math.Sqrt((double)((center.Y - y) * (center.Y - y)   (center.X - x) * (center.X - x)));

            if (y == center.Y && x > center.X)
            {
                dbl = 0d;
                angle = dbl;

                return;
            }
            else if (x == center.X && y > center.Y)
            {
                dbl = 90d;
                angle = dbl;

                return;
            }
            else if (y == center.Y && x < center.X)
            {
                dbl = 180d;
                angle = dbl;

                return;
            }
            else if (x == center.X && y < center.Y)
            {
                dbl = 279d;
                angle = dbl;

                return;
            }
            else if (x == center.X && y == center.Y)
            {
                angle = dbl;

                return;
            }

            if (x > center.X && y > center.Y) //1
            {
                dbl = Math.Atan(((double)y - (double)center.Y) / ((double)x - (double)center.X));
                dbl = 180d * dbl / Math.PI;
            }
            else if (x < center.X && y > center.Y) //2
            {
                dbl = Math.Atan(((double)y - (double)center.Y) / ((double)center.X - (double)x));
                dbl = 180d * dbl / Math.PI;
                dbl = 180d - dbl;
            }
            else if (x < center.X && y < center.Y) //3
            {
                dbl = Math.Atan(((double)center.Y - (double)y) / ((double)center.X - (double)x));
                dbl = 180d * dbl / Math.PI;
                dbl  = 180d;
            }
            else //4
            {
                dbl = Math.Atan(((double)center.Y - (double)y) / ((double)x - (double)center.X));
                dbl = 180d * dbl / Math.PI;
                dbl = 360d - dbl;
            }


            angle = dbl;
        }

        private void ReturnTexture(Texture texture_take, List<Point> lstPnt, float[] anglArr, float angle, Bitmap bmpNew)
        {
            int i, j, stride = 2048;
            float angleBefore, angleAfter;
            GraphicsStream textureStream;
            Boolean bl = false;

            if (bmpNew.Width != 512 && bmpNew.Height != 512)
                throw new Exception("Bitmaps must be of same size.");

            //sets texture to complete transparent 
            unsafe
            {
                fixed (byte* p = argbValuesOfTransparentTexture)
                {
                    MemSet((IntPtr)p, 0x0, argbValuesOfTransparentTexture.Length);
                }
            }


            angleAfter = angle   23F;

            if (angleAfter >= 360F)
            {
                angleAfter -= 360F;
            }

            angleBefore = angleAfter - 46;

            if (angleBefore < 0F)
            {
                angleBefore  = 360F;
                bl = true;
            }

            BitmapData bmD = bmpNew.LockBits(new Rectangle(0, 0, bmpNew.Width, bmpNew.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            unsafe
            {
                byte* p = (byte*)bmD.Scan0.ToPointer();
                //checks all points and draws yellow only those who are inside the cone 
                for (i = 0; i < lstPnt.Count - 1; i  )
                {
                    if (anglArr[i] == -1F)
                    {
                        continue;
                    }

                    if (bl == true)
                    {
                        if (anglArr[i] <= angleAfter || anglArr[i] >= angleBefore) //if point angle is inside cone. Cone angle is 46 degrees 
                        {
                            if (distanceArray[i] <= distanceFromCenterPixels)
                            {
                                j = lstPnt[i].Y * stride   lstPnt[i].X * 4;

                                //yellow 
                                argbValuesOfTransparentTexture[j   0] = (byte)0;
                                argbValuesOfTransparentTexture[j   1] = (byte)255;
                                argbValuesOfTransparentTexture[j   2] = (byte)255;
                                argbValuesOfTransparentTexture[j   3] = (byte)255;

                                p[j] = (byte)0;
                                p[j   1] = (byte)0;
                                p[j   2] = (byte)255;
                                p[j   3] = (byte)255;
                            }

                        }
                    }
                    else
                    {
                        if (anglArr[i] <= angleAfter && anglArr[i] >= angleBefore) //if point angle is inside cone. Cone angle is 46 degrees 
                        {
                            if (distanceArray[i] <= distanceFromCenterPixels)
                            {
                                j = lstPnt[i].Y * stride   lstPnt[i].X * 4;

                                //yellow 
                                argbValuesOfTransparentTexture[j   0] = (byte)0;
                                argbValuesOfTransparentTexture[j   1] = (byte)255;
                                argbValuesOfTransparentTexture[j   2] = (byte)255;
                                argbValuesOfTransparentTexture[j   3] = (byte)255;

                                p[j] = (byte)0;
                                p[j   1] = (byte)0;
                                p[j   2] = (byte)255;
                                p[j   3] = (byte)255;
                            }

                        }
                    }

                }
            }
            //if (angle <= 360)
            //  pictureBox1.Image.Save(@"c:\coneimages\"   angle   ".gif");

            bmpNew.UnlockBits(bmD);



            {
                using (textureStream = texture_take.LockRectangle(0, LockFlags.None))
                {
                    textureStream.Write(argbValuesOfTransparentTexture);
                    texture_take.UnlockRectangle(0);
                }

                //if (angle <= 360)
                //  pictureBox1.Image.Save(@"c:\coneimages\"   angle   ".gif");
            }
        }

        private void FindPoints()
        {


            //Bitmap bmptest;
            GraphicsPath gp = new GraphicsPath();
            int x, y, p, j, wdthHght;
            int bytes;
            //byte error_ = 5;
            byte[] rgbValuesWithClouds;
            byte[] rgbValuesWithoutClouds;
            IntPtr ptr;
            Rectangle rect;
            BitmapData bitmap_Data;

            Bitmap bmpWithClouds; //No memory is allocated
            Bitmap bmpWithoutClouds; //No memory is allocated

            gp.AddEllipse(new RectangleF(73, 72, 367, 367));

            //gp.CloseFigure();

            //using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
            using (bmpWithClouds = new Bitmap(mymem))//@"D:\MyWeatherStation-Images-And-Icons\radartobmp.bmp")) //24 bit bitmap
            {
                rect = new Rectangle(0, 0, bmpWithClouds.Width, bmpWithClouds.Height);
                wdthHght = bmpWithClouds.Width;

                //Lock bitmap to copy its color information fast
                bitmap_Data = bmpWithClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithClouds.PixelFormat);
                ptr = bitmap_Data.Scan0;
                bytes = bitmap_Data.Stride * bmpWithClouds.Height;

                rgbValuesWithClouds = new byte[bytes];

                //copy color information to rgbValues array
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithClouds, 0, bytes);
                //we are done copying so unlock bitmap. We dont need it anymore
                bmpWithClouds.UnlockBits(bitmap_Data);
            }


            //using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
            using (bmpWithoutClouds = new Bitmap(
                @"D:\C-Sharp\Download File\Downloading-File-Project-Version-012\Downloading File\bin\x86\Release\WithoutClouds.bmp"))//su   "\\WithoutClouds.bmp")) //24 bit bitmap
            {
                rect = new Rectangle(0, 0, bmpWithoutClouds.Width, bmpWithoutClouds.Height);

                //Lock bitmap to copy its color information fast
                bitmap_Data = bmpWithoutClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithoutClouds.PixelFormat);
                ptr = bitmap_Data.Scan0;
                bytes = bitmap_Data.Stride * bmpWithoutClouds.Height;

                rgbValuesWithoutClouds = new byte[bytes];

                //copy color information to rgbValues array
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithoutClouds, 0, bytes);
                //we are done copying so unlock bitmap. We dont need it anymore
                bmpWithoutClouds.UnlockBits(bitmap_Data);
            }

            // Each position in these arrays, rgbValuesWithoutClouds and rgbValuesWithClouds, corresponds a color. eg
            // First pixel   Second pixel   Third pixel   Forth pixel .... // bitmaps
            //    B G R          B G R         B G R         B G R    .... // rgbValues arrays
            //bmptest = new Bitmap(512, 512);
            detectedPoints = new List<Point>();

            for (y = 0; y < wdthHght; y  )
            {
                j = 0;
                for (x = 0; x < wdthHght; x  )
                {

                    p = y * wdthHght * 3   j;

                    if (rgbValuesWithClouds[p] != rgbValuesWithoutClouds[p])
                    {
                        detectedPoints.Add(new Point(x, y));
                        //bmptest.SetPixel(x, y, Color.Red);
                    }

                    j  = 3;
                }
            }
        }
    }
}

this is how it was working with the old directx dll files with the class Doppler.cs it's old video clip i recorded back in time and it was working nice but i can't make it working now again with this old directx files.

old weather radar doppler effect

ins this case i used a moving red line to scan and detect the clouds pixels and color them in yellow the same idea i want to do with the unity radar.

or if there is a way to do it in csharp winforms but i just can't make it working again with the old directx dll files.

CodePudding user response:

I've made this just for fun, hope that it is what you need (the quality is low because its a gif)

https://imgur.com/a/cbzqg77

I have a bunch of support methods to make the behaviour, but the important part, and the one that you are looking for, is this check for who is inside a cone view

private void PingEnemies()
{
    // Check for objects inside a sphere
    var cubesInRange = Physics.OverlapSphere(transform.position, visionRadius, detectableLayer);

    foreach (var cube in cubesInRange)
    {
        // Then ignore the objects that was outside the cone 
        var directionToTarget = (cube.transform.position - transform.position).normalized;
        if (Vector3.Angle(transform.forward, directionToTarget) <= viewAngle * .5f)
        {
            cube.GetComponent<CubeComponent>().ResetAlpha(); // Here we have the enemies inside the cone
        }
    }
}
  • Related