Advertisement
Guest User

Sirisian

a guest
Apr 6th, 2009
2,693
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.85 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <vector>
  4. #include <cmath>
  5.  
  6. #include "Vector2.hpp"
  7.  
  8. namespace IntersectionFunctions
  9. {
  10.     struct IntersectionObject
  11.     {
  12.         std::vector<Vector2> points;
  13.  
  14.         void InsertSolution(float x, float y)
  15.         {
  16.             points.push_back(Vector2(x, y));
  17.         }
  18.  
  19.         void InsertSolution(Vector2 v)
  20.         {
  21.             points.push_back(v);
  22.         }
  23.  
  24.         int NumberOfSolutions()
  25.         {
  26.             return points.size();
  27.         }
  28.     };
  29.  
  30.     // Circle to Circle
  31.     IntersectionObject CircleToCircleIntersection(Vector2 circlePosition1, float radius1,
  32.                                                   Vector2 circlePosition2, float radius2)
  33.     {
  34.         IntersectionObject result;
  35.         float a, distSq, dist, h;
  36.         Vector2 d, r, v2;
  37.  
  38.         // d is the vertical and horizontal distances between the circle centers
  39.         d = circlePosition1 - circlePosition2;
  40.  
  41.         //distance squared between the circles
  42.         distSq = d.LengthSq();
  43.  
  44.         // Check for equality and infinite intersections exist
  45.         if (distSq == 0 && radius1 == radius2)
  46.         {
  47.             return result;
  48.         }
  49.  
  50.         //Check for solvability
  51.         if (distSq > (radius1 + radius2) * (radius1 + radius2))
  52.         {
  53.             // no solution. circles do not intersect
  54.             return result;
  55.         }
  56.  
  57.         if (distSq < abs(radius1 - radius2) * abs(radius1 - radius2))
  58.         {
  59.             // no solution. one circle is contained in the other
  60.             return result;
  61.         }
  62.        
  63.         if (distSq == (radius1 + radius2) * (radius1 + radius2))
  64.         {
  65.             //one solution
  66.             result.InsertSolution((circlePosition1 - circlePosition2) / (radius1 + radius2) * radius1 + circlePosition1);
  67.             return result;
  68.         }
  69.  
  70.         dist = sqrt(distSq);
  71.  
  72.         // 'point 2' is the point where the line through the circle
  73.         // intersection points crosses the line between the circle
  74.         // centers.
  75.  
  76.         // Determine the distance from point 0 to point 2
  77.         a = ((radius1 * radius1) - (radius2 * radius2) + distSq) / (2.0f * dist);
  78.  
  79.         // Determine the coordinates of point 2
  80.         v2 = circlePosition1 + d * (a / dist);
  81.  
  82.         // Determine the distance from point 2 to either of the intersection points
  83.         h = sqrt((radius1 * radius1) - (a * a));
  84.  
  85.         // Now determine the offsets of the intersection points from point 2
  86.         r = d * (h / dist);
  87.         r = r.Normal();
  88.  
  89.         // Determine the absolute intersection points
  90.         result.InsertSolution(v2 + r);
  91.         result.InsertSolution(v2 - r);
  92.  
  93.         return result;
  94.     }
  95.  
  96.     // Used only within this namespace
  97.     int PrivateLineToCircleIntersection(Vector2 vertex1, Vector2 vertex2,
  98.                                         Vector2 circlePosition, float radius,
  99.                                         Vector2 & solution1, Vector2 & solution2)
  100.     {
  101.         // Vector from point 1 to point 2
  102.         Vector2 vertex1to2 = vertex2 - vertex1;
  103.         // Vector from point 1 to the circle's center
  104.         Vector2 circleToVertex1 = circlePosition - vertex1;
  105.  
  106.         float dot = vertex1to2.Dot(circleToVertex1);
  107.         Vector2 proj1 = vertex1to2 * (dot / vertex1to2.LengthSq());
  108.  
  109.         Vector2 midpt = vertex1 + proj1;
  110.         Vector2 circleToMidpt = midpt - circlePosition;
  111.         float distSqToCenter = circleToMidpt.LengthSq();
  112.         if (distSqToCenter > radius * radius) return 0;
  113.         if (distSqToCenter == radius * radius)
  114.         {
  115.             solution1 = midpt;
  116.             return 1;
  117.         }
  118.         float distToIntersection;
  119.         if (distSqToCenter == 0)
  120.         {
  121.             distToIntersection = radius;
  122.         }
  123.         else
  124.         {
  125.             distToIntersection = sqrt(radius * radius - distSqToCenter);
  126.         }
  127.         vertex1to2 = vertex1to2.Normalize();
  128.         vertex1to2 *= distToIntersection;
  129.  
  130.         solution1 = midpt + vertex1to2;
  131.         solution2 = midpt - vertex1to2;
  132.         return 2;
  133.     }
  134.  
  135.     //Line to Circle
  136.     IntersectionObject LineToCircleIntersection(Vector2 vertex1, Vector2 vertex2,
  137.                                                 Vector2 circlePosition, float radius)
  138.     {
  139.         IntersectionObject result;
  140.         Vector2 solution1, solution2;
  141.         switch(PrivateLineToCircleIntersection(vertex1, vertex2, circlePosition, radius, solution1, solution2))
  142.         {
  143.         case 2:
  144.             result.InsertSolution(solution2);
  145.         case 1:
  146.             result.InsertSolution(solution1);
  147.             break;
  148.         }
  149.         return result;
  150.     }
  151.  
  152.     // Circle to Line
  153.     IntersectionObject CircleToLineIntersection(Vector2 circlePosition, float radius,
  154.                                                 Vector2 vertex1, Vector2 vertex2)
  155.     {
  156.         return LineToCircleIntersection(vertex1, vertex2, circlePosition, radius);
  157.     }
  158.  
  159.     // LineSegment to Circle
  160.     IntersectionObject LineSegmentToCircleIntersection(Vector2 vertex1, Vector2 vertex2,
  161.                                                        Vector2 circlePosition, float radius)
  162.     {
  163.         IntersectionObject result;
  164.         Vector2 solution1, solution2;
  165.         Vector2 vertex1to2 = vertex2 - vertex1;
  166.         Vector2 vertex1ToSolution1, vertex2ToSolution1, vertex1ToSolution2, vertex2ToSolution2;
  167.         switch(PrivateLineToCircleIntersection(vertex1, vertex2, circlePosition, radius, solution1, solution2))
  168.         {
  169.         case 2:
  170.             vertex1ToSolution2 = solution2 - vertex1;
  171.             vertex2ToSolution2 = solution2 - vertex2;
  172.             if (vertex1ToSolution2.Dot(vertex1to2) > 0 &&
  173.                 vertex2ToSolution2.Dot(vertex1to2) < 0)
  174.             {
  175.                 result.InsertSolution(solution2);
  176.             }
  177.         case 1:
  178.             vertex1ToSolution1 = solution1 - vertex1;
  179.             vertex2ToSolution1 = solution1 - vertex2;
  180.             if (vertex1ToSolution1.Dot(vertex1to2) > 0 &&
  181.                 vertex2ToSolution1.Dot(vertex1to2) < 0)
  182.             {
  183.                 result.InsertSolution(solution1);
  184.             }
  185.             break;
  186.         }
  187.         return result;
  188.     }
  189.  
  190.     // Circle to LineSegment
  191.     IntersectionObject CircleToLineSegmentIntersection(Vector2 circlePosition, float radius,
  192.                                                        Vector2 vertex1, Vector2 vertex2)
  193.     {
  194.         return LineSegmentToCircleIntersection(vertex1, vertex2, circlePosition, radius);
  195.     }
  196.  
  197.     // Ray to Circle
  198.     IntersectionObject RayToCircleIntersection(Vector2 vertex1, Vector2 vertex2,
  199.                                                Vector2 circlePosition, float radius)
  200.     {
  201.         IntersectionObject result;
  202.         Vector2 solution1, solution2;
  203.         Vector2 vertex1to2 = vertex2 - vertex1;
  204.         Vector2 vertex1ToSolution1, vertex1ToSolution2;
  205.         switch(PrivateLineToCircleIntersection(vertex1, vertex2, circlePosition, radius, solution1, solution2))
  206.         {
  207.         case 2:
  208.             vertex1ToSolution2 = solution2 - vertex1;
  209.             if (vertex1ToSolution2.Dot(vertex1to2) > 0)
  210.             {
  211.                 result.InsertSolution(solution2);
  212.             }
  213.         case 1:
  214.             vertex1ToSolution1 = solution1 - vertex1;
  215.             if (vertex1ToSolution1.Dot(vertex1to2) > 0)
  216.             {
  217.                 result.InsertSolution(solution1);
  218.             }
  219.             break;
  220.         }
  221.         return result;
  222.     }
  223.  
  224.     // Circle to Ray
  225.     IntersectionObject CircleToRayIntersection(Vector2 circlePosition, float radius,
  226.                                                Vector2 vertex1, Vector2 vertex2)
  227.     {
  228.         return RayToCircleIntersection(vertex1, vertex2, circlePosition, radius);
  229.     }
  230.  
  231.     // Used only within this namespace
  232.     bool PrivateLineToLineIntersection(Vector2 vertex1, Vector2 vertex2,
  233.                                        Vector2 vertex3, Vector2 vertex4, float & r, float & s)
  234.     {
  235.         float d;
  236.         //Make sure the lines aren't parallel
  237.         Vector2 vertex1to2 = vertex2 - vertex1;
  238.         Vector2 vertex3to4 = vertex4 - vertex3;
  239.         //if (vertex1to2.x * -vertex3to4.y + vertex1to2.y * vertex3to4.x != 0)
  240.         //{
  241.         if(vertex1to2.y / vertex1to2.x != vertex3to4.y / vertex3to4.x)
  242.         {
  243.             d = vertex1to2.x * vertex3to4.y - vertex1to2.y * vertex3to4.x;
  244.             if (d != 0)
  245.             {
  246.                 Vector2 vertex3to1 = vertex1 - vertex3;
  247.                 r = (vertex3to1.y * vertex3to4.x - vertex3to1.x * vertex3to4.y) / d;
  248.                 s = (vertex3to1.y * vertex1to2.x - vertex3to1.x * vertex1to2.y) / d;
  249.                 return true;
  250.             }
  251.         }
  252.         return false;
  253.     }
  254.  
  255.     // Line to Line
  256.     IntersectionObject LineToLineIntersection(Vector2 vertex1, Vector2 vertex2,
  257.                                               Vector2 vertex3, Vector2 vertex4)
  258.     {
  259.         IntersectionObject result;
  260.         float r, s;
  261.         if(PrivateLineToLineIntersection(vertex1, vertex2, vertex3, vertex4, r, s))
  262.         {
  263.             result.InsertSolution(vertex1 + (vertex2 - vertex1) * r);
  264.         }
  265.         return result;
  266.     }
  267.  
  268.     // LineSegment to LineSegment
  269.     IntersectionObject LineSegmentToLineSegmentIntersection(Vector2 vertex1, Vector2 vertex2,
  270.                                                             Vector2 vertex3, Vector2 vertex4)
  271.     {
  272.         IntersectionObject result;
  273.         float r, s;
  274.         if(PrivateLineToLineIntersection(vertex1, vertex2, vertex3, vertex4, r, s))
  275.         {
  276.             if (r >= 0 && r <= 1)
  277.             {
  278.                 if (s >= 0 && s <= 1)
  279.                 {
  280.                     result.InsertSolution(vertex1 + (vertex2 - vertex1) * r);
  281.                 }
  282.             }
  283.         }
  284.         return result;
  285.     }
  286.  
  287.     // LineSegment to Line
  288.     IntersectionObject LineSegmentToLineIntersection(Vector2 vertex1, Vector2 vertex2,
  289.                                                      Vector2 vertex3, Vector2 vertex4)
  290.     {
  291.         IntersectionObject result;
  292.         float r, s;
  293.         if(PrivateLineToLineIntersection(vertex1, vertex2, vertex3, vertex4, r, s))
  294.         {
  295.             if (r >= 0 && r <= 1)
  296.             {
  297.                 result.InsertSolution(vertex1 + (vertex2 - vertex1) * r);
  298.             }
  299.         }
  300.         return result;
  301.     }
  302.  
  303.     // Line to LineSement
  304.     IntersectionObject LineToLineSegmentIntersection(Vector2 vertex1, Vector2 vertex2,
  305.                                                      Vector2 vertex3, Vector2 vertex4)
  306.     {
  307.         return LineSegmentToLineIntersection(vertex3, vertex4, vertex1, vertex2);
  308.     }
  309.  
  310.     // Ray to LineSegment
  311.     IntersectionObject RayToLineSegmentIntersection(Vector2 vertex1, Vector2 vertex2,
  312.                                                     Vector2 vertex3, Vector2 vertex4)
  313.     {
  314.         IntersectionObject result;
  315.         float r, s;
  316.         if(PrivateLineToLineIntersection(vertex1, vertex2, vertex3, vertex4, r, s))
  317.         {
  318.             if (r >= 0)
  319.             {
  320.                 if (s >= 0 && s <= 1)
  321.                 {
  322.                     result.InsertSolution(vertex1 + (vertex2 - vertex1) * r);
  323.                 }
  324.             }
  325.         }
  326.         return result;
  327.     }
  328.  
  329.     // LineSegment to Ray
  330.     IntersectionObject LineSegmentToRayIntersection(Vector2 vertex1, Vector2 vertex2,
  331.                                                     Vector2 vertex3, Vector2 vertex4)
  332.     {
  333.         return RayToLineSegmentIntersection(vertex3, vertex4, vertex1, vertex2);
  334.     }
  335.  
  336.     // Ray to Line
  337.     IntersectionObject RayToLineIntersection(Vector2 vertex1, Vector2 vertex2,
  338.                                              Vector2 vertex3, Vector2 vertex4)
  339.     {
  340.         IntersectionObject result;
  341.         float r, s;
  342.         if(PrivateLineToLineIntersection(vertex1, vertex2, vertex3, vertex4, r, s))
  343.         {
  344.             if (r >= 0)
  345.             {
  346.                 result.InsertSolution(vertex1 + (vertex2 - vertex1) * r);
  347.             }
  348.         }
  349.         return result;
  350.     }
  351.  
  352.     // Line to Ray
  353.     IntersectionObject LineToRayIntersection(Vector2 vertex1, Vector2 vertex2,
  354.                                              Vector2 vertex3, Vector2 vertex4)
  355.     {
  356.         return RayToLineIntersection(vertex3, vertex4, vertex1, vertex2);
  357.     }
  358.  
  359.     // Ray to Ray
  360.     IntersectionObject RayToRayIntersection(Vector2 vertex1, Vector2 vertex2,
  361.                                             Vector2 vertex3, Vector2 vertex4)
  362.     {
  363.         IntersectionObject result;
  364.         float r, s;
  365.         if(PrivateLineToLineIntersection(vertex1, vertex2, vertex3, vertex4, r, s))
  366.         {
  367.             if (r >= 0)
  368.             {
  369.                 if (s >= 0)
  370.                 {
  371.                     result.InsertSolution(vertex1 + (vertex2 - vertex1) * r);
  372.                 }
  373.             }
  374.         }
  375.         return result;
  376.     }
  377. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement