usingMaths.com
From Theory to Practice - Math You Can Use.







<< PreviousNext >>

Detecting Straight Line Regions in C++ | Detect Crossing & Region Division Tutorial




Detecting Regions Divided by a Diagonal Line | Maths Explanation for C++ Kids

In this tutorial, you'll learn how to detect when an object crosses a straight line in C++. We'll explore how to check which side of a line a point lies on, and how to apply this logic to a C++ canvas animation.

When working with graphics or simulations in C++, you might need to check which side of a line a ball or object is on. This technique is common in C++ canvas collision detection and helps define regions divided by a line.

Consider a moving body (circle). When it moves across a diagonal straight line, we can perform an action - such as changing the ball's colour - after it crosses from one region to another.

C++ diagram showing object crossing a straight line region
Figure: C++ diagram showing object crossing a straight line region


Understanding the Straight Line Equation in C++

We use the slope-intercept formula (y = mx + c) to define boundaries for region detection in C++.

To implement straight line region detection, we'll compare the ball's x-position with the position of the line at the same y-coordinate, using the line equation in C++.
If the ball's midpoint is (xb, yb) and the line at that height is (xl, yl), then:
         xl = myd + c
The ball crosses the line when: xd >= xl.

C++ straight line region diagram showing object coordinates for line detection
Figure: C++ straight line region diagram showing object coordinates for line detection

This logic uses the line equation in C++ to check when an object moves from one region to another.
This can also help with collision detection and boundary demarcation in C++ graphics or HTML canvas.

C++ Code: Detecting Line Crossing in Canvas

To determine which side of a diagonal boundary a point belongs to, we use a simple line equation. This C++ example demonstrates line region detection using the slope-intercept method.

Create a new C++ project; call it Dymetric.
Create 2 new C++ class files;
Call them Facet and StraightLineRegion.
Type out the adjoining C++ code for detecting the instance a travelling body crosses the path of a straight line.
This C++ line crossing detection example changes the ball's colour once it moves across the line.



Summary: Detecting Line Boundaries with C++

You've learned how to use the line equation in C++ to **detect regions divided by a straight line and trigger actions when objects cross the line**. This simple logic forms the foundation of C++ graphics and animation algorithms.

By now, you can use C++ to detect when an object crosses a straight line and determine which region it belongs to. This simple mathematical approach is useful for animations, physics simulations, and canvas line region detection.

Applying the Line Region Detection Logic in C++

This tutorial teaches you to:

  • Detect when a ball crosses a straight or diagonal line.
  • Identify which side of a line a point lies on.
  • Create interactive C++ canvas projects with region-based logic.

You can extend this principle to handle collision detection, line-segment intersection, or more complex 2D graphics region detection.



So! C++ Fun Practice Exercise - Detect Straight Line Boundary

As a fun practice exercise, try modifying the C++ code to explore different coordinates and intercepts. This will be a great way to connect mathematics and programming, and help you understand more about C++ animations and linear boundaries.







C++ Straight Line Boundary Dymetric Window Code Stub


C++ Straight Line Boundary Canvas Frame and Button Controls - Header File

#pragma once

class Facet
{
public:
    Facet(HWNDintint);
    virtual ~Facet();
    bool decorateButton(WPARAMLPARAM);
    bool actionPerformed(HWNDWPARAMLPARAM);
    void informPaint();
};


C++ Straight Line Boundary Canvas Frame and Button Controls - Class File

#include "stdafx.h"
#include "Facet.h"
#include "StraightLineRegion.h"

StraightLineRegion* boundary;

/*
* Our custom class that interfaces between the parent window
* and the subsequent daemonstrator classes
*/

Facet::Facet(HWND hWndint window_widthint window_height)
{
    boundary = new StraightLineRegion(hWndwindow_widthwindow_height);
}


/*
* This guy decorates buttons with colour and title text
*/

bool Facet::decorateButton(WPARAM wParamLPARAM lParam) {
    // button glide calling
    if (wParam == 12321)
    {
        LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
        
        SetDCBrushColor(lpDIS->hDC, RGB(255, 192, 203));
        SelectObject(lpDIS->hDC, GetStockObject(DC_BRUSH));

        RECT rect = { 0 };
        rect.left = lpDIS->rcItem.left;
        rect.right = lpDIS->rcItem.right;
        rect.top = lpDIS->rcItem.top;
        rect.bottom = lpDIS->rcItem.bottom;

        RoundRect(lpDIS->hDC, rect.left, rect.top, rect.right, rect.bottom, 50, 50);
        // button text
        DrawText(lpDIS->hDC, TEXT("MOVE"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        
        return TRUE;
    }
    return FALSE;
}

/*
* Call the target class' draw method
*/

void Facet::informPaint() {
    boundary->paint();
}


/*
* Say there is more than a single push button,
* this guy picks out the correct button that got clicked
* and calls the corresponding apt function
*/

bool Facet::actionPerformed(HWND hWndWPARAM wParamLPARAM lParam)
{
    switch (LOWORD(wParam))
    {
    case 12321:
        boundary->checkBoundary();
        return TRUE;
    default:
        return FALSE;
    }
}

Facet::~Facet()
{
    delete boundary;
}

C++ Animation Code for Straight Line Region - Header File

#pragma once

#define aWIDTH 80
#define aHEIGHT 80

class StraightLineRegion
{
public:
    StraightLineRegion(HWNDintint);
    virtual ~StraightLineRegion();
    void paint();
    void checkBoundary();
protected:
    HWND hWindow;
    HDC hdc;
    int window_width;
    int window_height;
    COLORREF ball_colour;
    // coordinates for the ball(circle)
    int x_ball;
    int y_ball;
    int previous_x;
    int previous_y;

    int x1;
    int x2;
    int y1;
    int y2;
    // x-coordinate for diagonal line
    double x_line;
    double m, c; // slope and y-intercept of a straight line

    HPEN background_pen;
    HBRUSH background_brush;
    HPEN ball_pen;
    HBRUSH ball_brush;
};


C++ Animation Code for Straight Line Region - Class File

#include "stdafx.h"
#include "StraightLineRegion.h"


StraightLineRegion::StraightLineRegion(HWND hWndint window_widthint window_height)
{
    hWindow = hWnd// save away window handle
    this->window_width = window_width// save away window width
    this->window_height = window_height// save away window width

    ball_colour = RGB(255, 255, 0); // yellow for our travelling ball colour
    x_ball = 50;
    y_ball = 200;
    previous_x = x_ball;
    previous_y = y_ball;

    x1 = 400;
    x2 = 600;
    y1 = 410;
    y2 = 110;

    m = (double)(y2 - y1) / (x2 - x1); // slope
    c = (double)(x2 * y1 - x1 * y2) / (x2 - x1); // y-intercept

    x_line = (double)(y_ball - c) / m;

    // Pen and brush matching background colour
    background_pen = CreatePen(PS_SOLID, 1, RGB(192, 192, 192));
    background_brush = CreateSolidBrush(RGB(192, 192, 192));

    // Pen and brush for travelling ball
    ball_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
    ball_brush = CreateSolidBrush(ball_colour);

    hdc = GetDC(hWindow);
}

/*
* draws the ball/circle using the apt color
*/

void StraightLineRegion::paint() {
    SelectObject(hdc, ball_pen); // use a black pen
    //draw diagonal line
    MoveToEx(hdc, x1, y1, NULL);
    LineTo(hdc, x2, y2);

    SelectObject(hdc, background_pen); // select background colour
    SelectObject(hdc, background_brush); // select background colour
    // erase previous circle
    Ellipse(hdc, previous_x, previous_y, previous_x + aWIDTH, previous_y + aHEIGHT);

    SelectObject(hdc, ball_pen); // select ball colour
    SelectObject(hdc, ball_brush);
    // draw a circle
    Ellipse(hdc, x_ball, y_ball, x_ball + aWIDTH, y_ball + aHEIGHT);
    
    previous_x = x_ball;
}

/*
Repeatedly draws ball so as to simulate a continuous motion
*/

void StraightLineRegion::checkBoundary() {
    // condition for continuing motion
    while (x_ball + aWIDTH <= window_width) {
        if (x_ball >= x_line) { // we could make this happen just once, but...
            ball_colour = RGB(0, 255, 0); // green color for our moving body(circle)

            DeleteObject(ball_brush); // delete former brush
            ball_brush = CreateSolidBrush(ball_colour); // recreate brush with a new colour
        }
        paint();

        x_ball += 10;
        // introduce a delay between renderings
        Sleep(50);
    }
}


StraightLineRegion::~StraightLineRegion()
{
    DeleteObject(background_pen);
    DeleteObject(background_brush);

    DeleteObject(ball_pen);
    DeleteObject(ball_brush);

    ReleaseDC(hWindow, hdc);
}





<< PreviousNext >>