Welcome to Dream.In.Code
Getting C++ Help is Easy!

Join 136,789 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 2,312 people online right now. Registration is fast and FREE... Join Now!




Field of View

 
Reply to this topicStart new topic

Field of View

EFuller
3 Oct, 2008 - 04:41 PM
Post #1

New D.I.C Head
*

Joined: 3 Oct, 2008
Posts: 1

I have to determine if the point falls inside or outside the field of view of a camera. If the point falls inside the field of view of a camera, it will be colored green. If the point falls outside the field of view of a camera, it will be colored red. i have the formula for the dot product but I need help in translating it. And I am just lost on how to color the line.

The dot product can be used to find the angle between vectors. Note the angle between the vectors CamDirection and userPoint if userPoint is in the field of view of the camera.

CODE

/*
fov.cpp

Determines the field of view extents for a given camera direction and fov angle
*/

#include <math.h>
#include <stdio.h>
#include <windows.h>

#include "resource.h"

// your path for this include may vary
#include "GraphicsFramework.h"

// Global variable to store the graphics framwork object
GraphicsFramework* PGraphics;

HWND HOutput = 0;  // handle to the output control
HWND HDialog = 0;

const double PI = 3.1415927;

// 2D point or vector
struct Vector2 {    
    double x, y;        // coordinates

    // default constructor - sets coordinates to 0
    Vector2() {
        x = y = 0.0;
    }

    // returns the squared length of this vector
    double squaredLength() {
        return((x * x) + (y * y));
    }
    
    // returns length of this vector
    double length() {
        return(sqrt(squaredLength()));
    }

    // normalizes this vector
    void normalize() {
        double len = length();
        // make sure we don't divide by zero
        if (len != 0.0) {
            scale(1 / length());
        }
    }

    // scales this vector uniformly by s
    void scale(double s) {
            x *= s;  
            y *= s;        
    }

};

// return the dot product of vectors a and b
double Vector2Dot(Vector2 a, Vector2 B)
{
    return((a.x * b.x) + (a.y * b.y));
}
    
    

// function to get the absolute value of an integer
int Abs(int x) {
    if (x < 0)  return -x;
    else        return x;
}

// function to get the sign (+1 or -1) of an integer
int Sign(int x) {
    if (x < 0)  return -1;
    else        return 1;
}


void Circle(int xCenter, int yCenter, int r, unsigned int color) {
    double d;
    int rSquared;
    int x, y;

    rSquared = r * r;

    x = 0;
    y = r;

    d = rSquared - ((x + 1) * (x + 1) + (y - 0.5) * (y - 0.5));

    while (y >= x) {
        PGraphics->AddPoint(xCenter + x, yCenter + y, color);
        PGraphics->AddPoint(xCenter - x, yCenter + y, color);
        PGraphics->AddPoint(xCenter + x, yCenter - y, color);
        PGraphics->AddPoint(xCenter - x, yCenter - y, color);
        PGraphics->AddPoint(xCenter + y, yCenter + x, color);
        PGraphics->AddPoint(xCenter - y, yCenter + x, color);
        PGraphics->AddPoint(xCenter + y, yCenter - x, color);
        PGraphics->AddPoint(xCenter - y, yCenter - x, color);
        if (d > 0) {
        }
        else {
            y--;
        }
        x++;
        d = rSquared - ((x + 1) * (x + 1) + (y - 0.5) * (y - 0.5));
    }
}

// function to draw a line between two points
void DrawLine(int x1, int y1, int x2, int y2, unsigned int color) {
    int dx, dy;                         // dy / dx is the slope
    int x, y;                           // loop and point variables

    // calculate changes in y and x between the points
    dy = y2 - y1;
    dx = x2 - x1;

    if (Abs(dy) > Abs(dx)) {
        // since there is a greater change in y than x we must
        // loop in y, calculate x and draw
        for (y=y1; y != y2; y += Sign(dy)) {
            x = x1 + (y - y1) * dx / dy;
            PGraphics->AddPoint(x, y, color);
        }
    }
    else {
        // since there is a greater (or equal) change in x than y we must
        // loop in x, calculate y and draw
        for (x=x1; x != x2; x += Sign(dx)) {
            y = y1 + (x - x1) * dy / dx;
            PGraphics->AddPoint(x, y, color);
        }
    }

    // draw the last pixel
    PGraphics->AddPoint(x2, y2, color);
}

// function to return the bounding angle of a camera's field of view
// assumes camera is at the origin
// v1, v2 will be filled in with the 1st & 2nd (going CCW) bounding vectors
// for the given camera direction and field of view
// v1 and v2 will be normalized
void GetFOVExtents(Vector2 camDir, double fov, Vector2* v1, Vector2* v2) {
    double camAngle;        // camera angle in standard position
    double a1, a2;          // angles of fov bounding vectors v1 & v2 in std pos

    // calculate the camera angle = arctan(y/x)
    // use the atan2 function to account for different quadrants
    camAngle = atan2(camDir.y, camDir.x);

    // calculate the angles of the bounding vectors on either side of the fov
    // fov is in degrees must convert to radians in calculations
    a1 = camAngle - fov/2 * (PI/180);
    a2 = camAngle + fov/2 * (PI/180);
    
    // calculate the fov bounding vectors
    v1->x = cos(a1);
    v1->y = sin(a1);
    v2->x = cos(a2);
    v2->y = sin(a2);
}

void DrawStuff() {
    COLORREF green = RGB(0, 255, 0);    // green color to draw with
    COLORREF red = RGB(255, 0, 0);      // red color to draw with
    COLORREF blue = RGB(0, 0, 255);     // blue color to draw with
    Vector2 camDirection;
    Vector2 userPoint;
    
    Vector2 fovPt1, fovPt2;             // field of view extent points
    double fov;                         // camera field of view (in degrees)

    char str[32];                       // string to store user input
    RECT rect;                          // rectangle for the output window
    int xMin, xMax, wdRect;             // min & max x rectangle coords

    // clear the scene and add an axis
    PGraphics->ClearScene(RGB(0, 0, 0));
    PGraphics->AddAxis(RGB(150, 150, 150), 10);

    // get the rectangle info for this window
    GetClientRect(HOutput, &rect);
    wdRect = rect.right - rect.left;
    xMin = -wdRect / 2;
    xMax =  wdRect / 2;

    // get the user input from the edit boxes and
    // convert string input to double
    GetDlgItemText(HDialog, IDC_EDIT_CAMDIRX, str, 32);
    camDirection.x = atof(str);
    GetDlgItemText(HDialog, IDC_EDIT_CAMDIRY, str, 32);
    camDirection.y = atof(str);
    GetDlgItemText(HDialog, IDC_EDIT_POINTX, str, 32);
    userPoint.x = atof(str);
    GetDlgItemText(HDialog, IDC_EDIT_POINTY, str, 32);
    userPoint.y = atof(str);
    GetDlgItemText(HDialog, IDC_EDIT_VIEWANGLE, str, 32);
    fov = atof(str);

    // get the normalized fov extent points
    GetFOVExtents(camDirection, fov, &fovPt1, &fovPt2);

    // scale these points before drawing the fov rays
    fovPt1.scale(50);
    fovPt2.scale(50);

    // draw the fov rays
    DrawLine(0, 0, fovPt1.x, fovPt1.y, green);
    DrawLine(0, 0, fovPt2.x, fovPt2.y, green);

    // determine if user point is within the field of view here
    //we are assuming carmera location is at origin
    //*************************************
                float dot_product(float *a,float *b,int size)
{
    float dp = 0.0f;
    for (int i=0;i<size;i++)
        dp += a[i] * b[i];
    return dp;
}



    Circle(userPoint.x, userPoint.y, 1, blue);
//You are to color this point green or red,
//depending on whether or not it is inside                                      
//or outside fov. An if statement may be used
if( userPoint.x * userPoint.y < 0)
  line (
    


    // draw the points
    PGraphics->Draw();
}

/*
DialogProc
this is the window event handler for the main dialog
*/
BOOL CALLBACK DialogProc (HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    switch(message)
    {
    case WM_INITDIALOG:
        // dialog is initializing - store the picture box handle in a global variable for later
        HOutput = GetDlgItem(hwnd, IDC_PICTURE_OUTPUT);        

        // instantiate and initialize our graphics framework object
        PGraphics = new GraphicsFramework(HOutput);

        break;

    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
            case IDC_BTN_DRAW:
                // draw button was pressed
                DrawStuff();
                break;
            case IDC_BTN_CLEAR:
                // clear button was pressed so clear the scene and draw the empty scene
                PGraphics->ClearScene(RGB(0, 0, 0));
                PGraphics->Draw();
                break;
            case IDCANCEL:
                // user is quitting so release the GraphicsFramework object and quit
                delete PGraphics;
                PostQuitMessage(0);
                break;
        }
                  
    }
    return FALSE;
}

// this is the main function that starts the application
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
    // create the main window
    // store its handle in a global if needed
    HDialog = CreateDialog (GetModuleHandle(NULL),
        MAKEINTRESOURCE(IDD_DIALOG1),
        0,
        DialogProc);

    // make the dialog visible
    ShowWindow(HDialog, SW_SHOW);

    // standard windows message loop
    MSG  msg;
    int status;
    while ((status = GetMessage (&msg, 0, 0, 0)) != 0)
    {
        if (status == -1)
            return -1;
        // avoid processing messages for the dialog
        if (!IsDialogMessage (HDialog, & msg))
        {
            TranslateMessage ( & msg );
            DispatchMessage ( & msg );
        }
    }

    return (int)(msg.wParam);
}



This post has been edited by Jayman: 29 Nov, 2008 - 08:48 AM
User is offlineProfile CardPM
+Quote Post

the_dehumanizer
RE: Field Of View
29 Nov, 2008 - 07:00 AM
Post #2

New D.I.C Head
*

Joined: 8 Nov, 2008
Posts: 3

Here is the bread and butter to make it work.
CODE

    // edited by Brian Whisenant
    //This takes the dot product of the cam direction and the user point vector and finds the angle between them
    //it then checks to see if that angle is less-than or equal to the field of view and colors the circle
    //based on the condition.

    if (acos(Vector2Dot(camDirection, userPoint)/(camDirection.length() * userPoint.length())) * (180/PI) <= fov/2) {
        Circle(userPoint.x, userPoint.y, 1, green);
    }
    else {
        Circle(userPoint.x, userPoint.y, 1, red);
    }
    //*
    //*
    // *************************************************
    


This post has been edited by the_dehumanizer: 29 Nov, 2008 - 07:02 AM
User is offlineProfile CardPM
+Quote Post

Reply to this topicStart new topic
Time is now: 12/3/08 01:31PM

Live C++ Help!

C++ Tutorials

Reference Sheets

C++ Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month