Projects in Visual C++ 2010 – Part 1: Creating a DLL project

When you write software, you often/sometimes divide your project into several subprojects. This mini series describes how to do this with Visual C++ 2010 (but this first part also applies to earlier versions). We start with creating a library project in form of a DLL.

Related articles:

Read more →

C++/CLI Cheat Sheet

This article provides a quick comparison between C++/CLI and C#. It’s meant for those who know C# (and possibly C++) and will explain which C++/CLI language construct correspond with which in C#. (I don’t know Visual Basic so I can’t add infos about this here.)

Note: This is not a complete reference but rather quick reference for those features that are (in my opinion) the most unclear.

Read more →

Android Source Code in Eclipse

Google made developing an Android app fairly simple. Everything you need can be downloaded for free from Android’s development site. This includes the Android API, an Android emulator (for running Android apps directly on your computer), and an Eclipse plugin called ADT (Android Developer Tools). However, there is was one thing missing: the Java source code.

Read more →

Rectangle Intersection Test (with C#)

For a software project I needed to check whether two rectangles intersect (or overlap). What made my problem complicated was that one of the rectangles could be rotated. While this problem seems to be trivial (to a human being), it’s not that simple to implement. It took me a while to find the right answer.

Intersecting Rectangles

Now, the solution to this problem is called a separating axis test. Basically this means: If I can find an axis (read: line) that separates both rectangles, then they don’t intersect/overlap. (Actually this works for any convex polygon; see below) Of course, if the two rectangles don’t intersect, there are undefinitely many possible separating axes. Fortunately we can use the edges of each rectangle as axes and testing all of the is sufficient.

An axis separating two rectangles

I won’t get into the details of this algorithm here – it’s sufficiently good described in the article mentioned above – but basically you check for each point on which side of the separating axis it is. If all points of the rectangle A are on one side and all of rectangle B are on the other side, then we’ve found a separating axis.

Here’s the implementation of the method testing where a single edge (represented by points x1 and x2) is a separating axis:

/// <summary>
/// Does axis separation test for a convex quadrilateral.
/// </summary>
/// <param name="x1">Defines together with x2 the edge of quad1 to be checked whether its a separating axis.</param>
/// <param name="x2">Defines together with x1 the edge of quad1 to be checked whether its a separating axis.</param>
/// <param name="x3">One of the remaining two points of quad1.</param>
/// <param name="otherQuadPoints">The four points of the other quad.</param>
/// <returns>Returns <c>true</c>, if the specified edge is a separating axis (and the quadrilaterals therefor don't 
/// intersect). Returns <c>false</c>, if it's not a separating axis.</returns>
bool DoAxisSeparationTest(Point x1, Point x2, Point x3, Point[] otherQuadPoints) {
  Vector vec = x2 - x1;
  Vector rotated = new Vector(-vec.Y, vec.X);

  bool refSide = (rotated.X * (x3.X - x1.X)
                + rotated.Y * (x3.Y - x1.Y)) >= 0;

  foreach (Point pt in otherQuadPoints) {
    bool side = (rotated.X * (pt.X - x1.X) 
               + rotated.Y * (pt.Y - x1.Y)) >= 0;
    if (side == refSide) {
      // At least one point of the other quad is one the same side as x3. Therefor the specified edge can't be a
      // separating axis anymore.
      return false;
    }
  }

  // All points of the other quad are on the other side of the edge. Therefor the edge is a separating axis and
  // the quads don't intersect.
  return true;
}

This method is then called for each edge of each rectangle. If the method returns true, the actual intersection test method can return “not intersecting”. If the method returns false for all edges, the rectangles intersect.

test-app.png

I’ve created an C#/WPF example implementation (under FreeBSD license) that you can download and experiment with.

Rectangle Intersection Test Project (for Visual Studio 2010)

Remarks: The algorithm above works for every convex polygon. Instead of four times two edges you then have n times m edges. For concave polygons, however, this algorithm doesn’t work because there may be no separating axis even though the polygons don’t intersect.

Triggering a build when file changed in Visual Studio

In Visual Studio when a source code file is changed, the project it belongs to will be built when the whole solution is being built. So far, so good. But what happens if you want some other files (read: non source code files) to have the same behavior?

In my case, I had some translation files (XML files), and a custom build event that converted them into a binary representation. So when one of translation files changed, I wanted this change to trigger a build for the project the translation files were contained in, so that they could be converted into binary form (ie. so that the build event was executed).

Visual Studio (at least version 2010) provides an easy but hidden way to achieve exactly this. After you’ve added the file(s) to your project, right-click them and choose Properties (Alt+Return).

The Properties menu item

Note: You need to open the properties for the files you want to trigger the build – don’t open the project’s properties. Also, you need to open the “Properties” dialog. You can’t do this from the “Properties” panel (which usually opens up when hitting F4).

Note 2: You can have selected multiple files to make them all triggering a build when changed in one step.

In the “Properties” dialog under Configuration Properties –> General –> Item Type you select Custom Build Tool. Then you hit “OK”. And that’s it.

Selecting "Custom Build Tool" as "Item Type".

Changing the file(s) should now trigger a build when you build the solution (via menu Build –> Build Solution).