• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            Controlling Players and Characters(11)

             

            Faster than the Speed of Pythagoras


            To determine the distance away from a route point, you can use the standard
            Pythagorean Theorem, but in order to speed things up, you can toss the sqrt
            operation out the door and use the sum of the squares of the lengths instead.
            To see what I mean, take a look at the following two lines of code:

            float Distance = sqrt(Length1*Length1 + Length2*Length2);
            float Distance = Length1*Length1 + Length2*Length2;

            Notice that the preceding two lines of code are almost identical, except the second
            line omits the sqrt function, making the second line execute much faster. The
            downside is that you don’t get the exact length, which really isn’t a problem.

            NOTE
            The Pythagorean Theorem is probably the most famous theorem in geometry. It states that the
            square of the length of the hypotenuse of a right triangle is equal to the sum of the squares of the
            lengths of the sides. Basically, it means that the square root of the lengths of two sides (when
            both are squared and added together) equals the length of the third side of a right triangle.

            For example, imagine that you are measuring the distance between two points and
            you want to see whether that distance is less than 40. If the coordinates of the two
            points are 0,0 and 30,20, the faster distance calculation will give you a distance of
            1,300 (because the length of the two sides are 30 and 20, respectively).

            How can you determine the distance now? By calculating the square (the number
            times itself) of the distance, that’s how! So, by taking 40 times 40, you get 1,600. By
            comparing the distance of 1,300 between the points, you can see that indeed the
            distance is less than 1,600 and, thus, less than the original distance of 40 you were
            checking.

            To get back to what I was originally talking about, you can use the faster method
            of distance calculation to determine when a character is close enough to a route
            point. Say that you want a route point considered as being touched by a character
            if that character comes within so many units from it. Utilizing the faster method of
            distance calculation, you can use the following function to determine whether that
            is the case:

            BOOL TouchedRoutePoint(
              float CharXPos, float CharZPos, // Character coordinates
              float RouteXPos, float RouteZPos, // Route point coordinates
              float Distance) // Distance to check
            {
              // Square the distance to adjust for faster distance checking
              Distance *= Distance;

              // Now calculate the distance
              float XDiff = (float)fabs(RouteXPos - CharXPos);
              float ZDiff = (float)fabs(RouteZPos - CharZPos);
              float Dist = XDiff*XDiff + ZDiff*ZDiff;

              // Return results
              if(Dist <= Distance) // Within range being checked
                return TRUE;

              return FALSE; // Out of distance range
            }

            When calling TouchedRoutePoint with the character coordinates, the coordinates of
            the route point, and the distance from the point to check, you will receive a value
            of TRUE if the character is within Distance units from the route point coordinates.
            A return value of FALSE means that the character is not within Distance units from
            the route point.

             

            Walking the Route
             

            At long last, you can put everything together and force a character to walk from
            one route point to the next. Here’s a small program that takes the five route points
            defined previously and puts a character at point one, forcing the character to walk
            from point to point forever:

            sRoutePoint Route[5] = {
              { -200.0f, -100.0f },
              { 100.0f, -300.0f },
              { 300.0f, -200.0f },
              { 200.0f, 100.0f },
              { 0.0f, 400.0f }
            };

            long NumRoutePoints = 5;

            // Character coordinates and movement variables
            float CharXPos = Route[0].XPos;
            float CharZPos = Route[0].ZPos;
            float MoveX, MoveZ;
            float Speed; // Walking speed of character

            // Start track to 2nd point
            long TargetRoutePoint = 1;
            SetupMovement(TargetRoutePoint);

            // Loop forever, moving and checking for route points reached
            while(1) {
              // Is character within range of route point?
              if(TouchedRoutePoint(TargetRoutePoint, 32.0f) == TRUE) {
                // Move to next route point
                TargetRoutePoint++;
                if(TargetRoutePoint >= NumRoutePoints)
                TargetRoutePoint = 0;
                SetupMovement(TargetRoutePoint);
              }

              // Move character
              CharXPos += MoveX;
              CharZPos += MoveZ;
            }

            // Function to check if within range of route point
            BOOL TouchedRoutePoint(long PointNum, float Distance)
            {
              Distance *= Distance;
              float XDiff = (float)fabs(CharXPos - Route[PointNum].XPos);
              float ZDiff = (float)fabs(CharZPos - Route[PointNum].ZPos);
              float Dist = XDiff*XDiff + ZDiff*ZDiff;


              if(Dist <= Distance)
                return TRUE;
             

              return FALSE;
            }

            // Function to calculate movement variables
            void SetupMovement(long PointNum)
            {
              float XDiff = (float)fabs(CharXPos - Route[PointNum].XPos);
              float ZDiff = (float)fabs(CharZPos - Route[PointNum].ZPos);
              float Length = sqrt(XDiff*XDiff + ZDiff*ZDiff);


              MoveX = (Route[PointNum].XPos - CharXPos) / Length * Speed;
              MoveZ = (Route[PointNum].ZPos - CharZPos) / Length * Speed;
            }


            posted on 2007-11-14 15:37 lovedday 閱讀(208) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            日本精品久久久久中文字幕8| 久久久久99精品成人片牛牛影视| 人妻久久久一区二区三区| 久久er99热精品一区二区| 热99re久久国超精品首页| 亚洲国产高清精品线久久| 精品久久久久久久| 国产偷久久久精品专区| 99久久www免费人成精品| 久久久久亚洲AV片无码下载蜜桃| 国产精品美女久久久久av爽| 亚洲色婷婷综合久久| 久久精品国产亚洲av瑜伽| 99久久精品国产麻豆| 午夜精品久久久久9999高清| 久久精品国产99国产电影网 | 蜜臀久久99精品久久久久久小说| 亚洲狠狠久久综合一区77777| 亚洲精品乱码久久久久久蜜桃不卡| 国产亚洲美女精品久久久| 久久九九久精品国产免费直播| 久久国产精品波多野结衣AV| 久久精品成人免费网站| 97精品国产91久久久久久| 亚洲国产精品无码成人片久久| 亚洲日本va午夜中文字幕久久 | 久久最新免费视频| 精品久久国产一区二区三区香蕉| 国产精品久久国产精麻豆99网站| 亚洲精品国产美女久久久| 亚洲精品无码久久久久| 久久久久女人精品毛片| 久久人人爽人人爽人人片AV不| 亚洲AV成人无码久久精品老人| 国产香蕉久久精品综合网| 三级三级久久三级久久| 婷婷伊人久久大香线蕉AV | 久久无码人妻精品一区二区三区 | 777午夜精品久久av蜜臀| 18禁黄久久久AAA片| 国内精品久久久久久久久电影网|