Étiquette : c++

  • Unity3D.tips[2]: Intersection point between two lines in 2D

    The code

    The maths behind

    To get the point where two lines intersect, we will do some maths. To the mathematicians who will come across this post, I’m truly sorry for the heart attacks or strokes you may experience by reading this post.

    Ok, let’s take a look on the figure:

    Study case. We can see two lines crossing in an 2D Euclidian space.
    Figure 1

    First, sorry, I was too lazy to make a proper figure using computer tools so I just put a scan. XD

    Next, here are the definitions:

    • AA & BB: the two lines,
    • A1A_1, B1B_1: the arbitrary starting points of the two lines,
    • A2A_2, B2B_2: the arbitrary points which tells the direction of the two lines,
    • XX: the intersection point,
    • OO: the origin point.

    Kewl. Now, what we want is the intersection point XX between those two lines. In other words, we want to know the position which starts from either lines’ arbitrary starting point, added by the direction of the line multiplied by a scalar value. So in our figure 1, the XX position is:

    • the A1A_1 position added by the components of A1A2\overrightarrow{A_1A_2} multiplied by an unknown which I named λ\lambda
    • the B1B_1 position added by the components of B1B2\overrightarrow{B_1B_2} multiplied by an unknown which I named μ\mu

    In this case, it is clear that λ=μ=0.5\lambda = \mu = 0.5 so it will be easy to check if our final formula is correct. 🙂

    At the point of intersection, we know that:

    OX=OA1+λ×A1A2andOX=OB1+μ×B1B2\begin{array}{rcl} \overrightarrow{OX} = \overrightarrow{OA_1} + \lambda\times\overrightarrow{A_1A_2} & and & \overrightarrow{OX} = \overrightarrow{OB_1} + \mu\times\overrightarrow{B_1B_2} \end{array}

    … which gives us:

    OA1+λ×A1A2=OB1+μ×B1B2OA1OB1=μ×B1B2λ×A1A2\begin{array}{rcl} \overrightarrow{OA_1} + \lambda\times\overrightarrow{A_1A_2} & = & \overrightarrow{OB_1} + \mu\times\overrightarrow{B_1B_2} \\ \overrightarrow{OA_1} – \overrightarrow{OB_1} & = & \mu\times\overrightarrow{B_1B_2} – \lambda\times\overrightarrow{A_1A_2} \end{array}

    But we can’t use this statement exactly like this to solve our equation as we cannot multiply and divide vectors in this raw format. Also we need to reduce the unkowns count to 1. So we will separate our equation into two equations with the magic of matrices (which I don’t understand well at the moment), one for the x component and one for the y:

    {OA1xOB1x=μ×B1B2xλ×A1A2xOA1yOB1y=μ×B1B2yλ×A1A2y\left\{\begin{array}{c}\overrightarrow{OA_1}_x – \overrightarrow{OB_1}_x = \mu\times\overrightarrow{B_1B_2}_x – \lambda\times\overrightarrow{A_1A_2}_x \\ \overrightarrow{OA_1}_y – \overrightarrow{OB_1}_y = \mu\times\overrightarrow{B_1B_2}_y – \lambda\times\overrightarrow{A_1A_2}_y \end{array}\right.

    To make our equation more readable, we will use some shorthands:

    Aα=A1A2,Bα=B1B2,C=OA1OB1\begin{array}{r}A_\alpha = \overrightarrow{A_1A_2}, & B_\alpha = \overrightarrow{B_1B_2}, & C = \overrightarrow{OA_1} – \overrightarrow{OB_1}\end{array}

    … so:

    {Cx=μBαxλAαxCy=μBαyλAαy\left\{\begin{array}{c} C_x = \mu B_{\alpha x} – \lambda A_{\alpha x} \\ C_y = \mu B_{\alpha y} – \lambda A_{\alpha y} \end{array}\right.

    From this point, we can reduce the unknown count. In my case, I have chosen to keep μ\mu instead of λ\lambda:

    {CxAαy=μBαxAαyλAαxAαyCyAαx=μBαyAαxλAαyAαx\left\{\begin{array}{c} C_x A_{\alpha y} = \mu B_{\alpha x} A_{\alpha y} – \lambda A_{\alpha x} A_{\alpha y} \\ C_y A_{\alpha x} = \mu B_{\alpha y} A_{\alpha x} – \lambda A_{\alpha y} A_{\alpha x} \end{array}\right.
    CxAαyCyAαx=μBαxAαyλAαxAαy(μBαyAαxλAαyAαx)CxAαyCyAαx=μBαxAαyλAαxAαyμBαyAαx+λAαyAαxCxAαyCyAαx=μBαxAαyμBαyAαxCxAαyCyAαx=μ(BαxAαyBαyAαx)μ=CxAαyCyAαxBαxAαyBαyAαx\begin{array}{rcl} C_x A_{\alpha y} – C_y A_{\alpha x} & = & \mu B_{\alpha x} A_{\alpha y} – \lambda A_{\alpha x} A_{\alpha y} – (\mu B_{\alpha y} A_{\alpha x} – \lambda A_{\alpha y} A_{\alpha x}) \\ C_x A_{\alpha y} – C_y A_{\alpha x} & = & \mu B_{\alpha x} A_{\alpha y} – \lambda A_{\alpha x} A_{\alpha y} – \mu B_{\alpha y} A_{\alpha x} + \lambda A_{\alpha y} A_{\alpha x} \\ C_x A_{\alpha y} – C_y A_{\alpha x} & = & \mu B_{\alpha x} A_{\alpha y} – \mu B_{\alpha y} A_{\alpha x} \\ C_x A_{\alpha y} – C_y A_{\alpha x} & = & \mu (B_{\alpha x} A_{\alpha y} – B_{\alpha y} A_{\alpha x}) \\ \mu & = & \frac{C_x A_{\alpha y} – C_y A_{\alpha x}}{B_{\alpha x} A_{\alpha y} – B_{\alpha y} A_{\alpha x}} \end{array}

    And finally, you have to check if BαxAαyBαyAαx=0B_{\alpha x} A_{\alpha y} – B_{\alpha y} A_{\alpha x} = 0. This will happen if your two lines are parallel or if there is one line defined as a point such as A1=A2A_1 = A_2 or B1=B2B_1 = B_2; no solution exists in those cases.

    Test 1

    Kewl! Now let’s try it with the Figure 1:

    μ=(11)×1(24)×22×1(3)×2μ=48=0.5\begin{array}{rcl} \mu & = & \frac{(1 – 1) \times 1 – (2 – 4) \times 2}{2 \times 1 – (-3) \times 2} \\ \mu & = & \frac{4}{8} = 0.5 \end{array}

    We can get the XX position:

    {OXx=OB1x+Bαx×μ=1+2×0.5=2OXy=OB1y+Bαy×μ=4+(3)×0.5=2.5\left\{\begin{array}{l} \overrightarrow{OX}_x = \overrightarrow{OB_1}_x + B_{\alpha x} \times \mu = 1 + 2 \times 0.5 = 2 \\ \overrightarrow{OX}_y = \overrightarrow{OB_1}_y + B_{\alpha y} \times \mu = 4 + (-3) \times 0.5 = 2.5 \end{array}\right.

    Test 2

    Ok done! Now let’s try with another figure:

    Study case 2. We can see two lines crossing in an 2D Euclidian space.
    Figure 2
    μ=((2)2)×(1)((2)(3))×0(1.5)×(1)1.5×0μ=41.52.666\begin{array}{rcl} \mu & = & \frac{((-2) – 2) \times (-1) – ((-2) – (-3)) \times 0}{(-1.5) \times (-1) – 1.5 \times 0} \\ \mu & = & \frac{4}{1.5} \approx 2.666 \end{array}

    We can get the XX position:

    {OXx=OB1x+Bαx×μ=2+(1.5)×2.666=2OXy=OB1y+Bαy×μ=(3)+1.5×2.666=1\left\{\begin{array}{l} \overrightarrow{OX}_x = \overrightarrow{OB_1}_x + B_{\alpha x} \times \mu = 2 + (-1.5) \times 2.666 = -2 \\ \overrightarrow{OX}_y = \overrightarrow{OB_1}_y + B_{\alpha y} \times \mu = (-3) + 1.5 \times 2.666 = 1 \end{array}\right.

  • ShellExecuteA n’ouvre pas d’URL sur Windows depuis un logiciel C++

    Je viens de passer trente minutes à chercher la solution à un problème empêchant d’ouvrir le navigateur par défaut sur Windows depuis un logiciel C++ via ShellExecuteA(), en l’occurrence, le jeu Esteren : Les Griffes du Seigneur Sorcier dont le kickstarter est toujours en cours au moment où j’écris cet article. 😛

    La solution dans mon cas a été de redéfinir le navigateur par défaut, par exemple en passant par Chrome puis en revenant à Firefox. Juste avec cette simple manipulation, le ShellExecuteA() a fonctionné de nouveau. C’est tout !

    Et oui, rien à voir avec un bug de votre code, c’est probablement de la faute des autres qui ne font pas bien leur boulot !

  • [C++] Ouvrir le navigateur depuis Cocos2d-x

    Il fallait que j’intègre des boutons dans un projet cocos2d-x pour rediriger sur des pages de réseaux sociaux. Mais à mon grand regret, il n’existe pas de fonction préparée dans le framework de cocos2d-x (version 3.2) pour ouvrir une page de navigateur. Il m’a alors fallu l’implémenter moi-même.

    Content.

    Fort heureusement, des personnes se sont déjà penchées sur la question et une source m’a été particulièrement utile. Pour info, ce qui va suivre pourrait aussi servir à ouvrir des fichiers en local (file://) ou toute ressource pointable par un URI (tant qu’il y a un logiciel qui peut gérer cet URI, of course) ! Mes chers lecteurs francophones (parce qu’aucun anglophone ou autre ne viendrait ici huhu), voici un récapitulatif :

    Partie Windows

    • cocos/platform/win32/CCApplication.h
    • cocos/platform/win32/CCApplication.cpp

    Partie Android

    • cocos/platform/android/CCApplication.h
    • cocos/platform/android/CCApplication.cpp
    • cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
      • À ajouter dans les imports si ce n’est pas déjà fait :
      • À ajouter dans la classe Cocos2dxActivity :

    Partie iOS (quand j’en aurai besoin :P)

    Conclusion

    Et voilà ! Désormais, pour ouvrir la page, appelez la méthode openUrl ainsi :

  • Générer un projet Visual Studio Community pour Windows XP

    Alors que je devais préparer un exécutable d’un projet sur Visual Studio Community (VS2013), j’ai dû configurer le projet pour que l’exécutable puisse fonctionner sur Windows XP. Les paramètres par défaut provoquent une erreur de type « application win32 non valide ».

    Pour corriger cela, il suffit d’aller dans les propriétés du projet et de définir Platform Toolset à Visual Studio 2013 – Windows XP (v120_xp). Ainsi, l’exécutable pourra fonctionner sur Windows XP si toutes les bibliothèques (dll) — telles que les pilotes et le package redistribuable Visual C++ 2013 — ont été installées.

    Configuration de projet VS2013 pour Windows XP
    Configuration de projet VS2013 pour Windows XP