"Go" game Programmer's Mathematical food 05--vector quick look table

Source: Internet
Author: User
Tags scalar

Original: http://gad.qq.com/program/translateview/7172922

Translation: Wang Chenglin (Maxwell's Maxwell) revision: Huang Xiumei (Heavy-tak)

This is the fifth article in this series that we have long been looking forward to. If you don't know much about vectors, check out the first four articles in this series: Introduction, Vector basics, vector geometry, vector operations.

This quick check list lists some of the common geometric problems in the game and how to solve them using mathematical vectors.

Complete form for basic vector operations

First, let's review it.

First I assume that you have a vector class available. Most of its functions are concentrated on the 2D, but the principle of 3D is the same. The difference is only in the vector product, in 2D I assume that a vector multiplication only returns a scalar representing the "z" axis. I will specifically point out any case that applies only to 2D or 3D.

Strictly speaking, a point is not a vector--but a vector can represent the distance from the origin (0,0) to the point, so it is reasonable to represent the vector as a dot.

I expect you to have each component in this class, and the following operations (using C + + style notation, including operator overloading – but depending on your needs it should be easy to translate it into any other language). If an operation is not available, you can still implement it by extending the class or by creating a "Vectorutils" class. The following examples generally apply to 2D vectors--but for 3D it is usually only possible to add Z coordinates in the form of x and Y.

    • vector2foperator+ (vector2f VEC): Returns the and of two vectors. (in languages that are not overloaded, the function may be called add ().) Here are a few examples similar. )

A+B=VECTOR2F (A.X+B.X,A.Y+B.Y);

    • vector2foperator- (vector2f VEC): Returns the difference between two vectors

A-B=VECTOR2F (A.X-B.X,A.Y-B.Y);

    • vector2foperator* (vector2f VEC): Returns the product of a component of two vectors

A*B=VECTOR2F (A.X*B.X,A.Y*B.Y);

    • vector2foperator/ (vector2f VEC): Returns a component quotient of two vectors

A/B=VECTOR2F (A.X/B.X,A.Y/B.Y);

    • vector2foperator* (float scalar): Returns the result of multiplying all the components of a vector by a scalar parameter, respectively.

A*S=VECTOR2F (a.x*s,a.y*s);

S*A=VECTOR2F (a.x*s,a.y*s);

    • vector2foperator/ (float scalar): Returns the result of each component of the vector divided by a scalar parameter.

A/S=VECTOR2F (A.X/S,A.Y/S);

    • Floatdot (vector2f VEC): Returns the dot multiplication of two vectors

A.dot (b) =a.x*b.x+a.y*b.y;

    • Floatcross (vector2f VEC): (2D case) returns the z component of a two-vector fork (3D vector)

A.cross (b) =a.x*b.y-a.y*b.x;

    • Vector3fcross (vector3f VEC): (3D case) returns the cross-multiplication of two vectors.

A.cross (b) =vector3f (A.Y*B.Z-A.Z*B.Y, a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);

    • Floatlength (): Returns the length of the vector.

A.length () =sqrt (A.X*A.X+A.Y*A.Y);

    • Floatsquaredlength (): Returns the square of the length of the vector. It is suitable for comparing the lengths of two vectors and avoids the calculation of square roots.

A.squaredlength () =a.x*a.x+a.y*a.y;

    • Floatunit (): Returns a vector that points to a length of 1 in the same direction.

A.unit () =a/a.length ();

    • Vector2fturnleft (): Returns the result of a vector rotated 90 degrees to the left. Applies to the calculation method vector. (Assuming the y-axis is pointing up, or turning right)

A.TURNLEFT=VECTOR2F (-a.y,a.x);

    • Vector2fturnright (): Returns the result of a vector rotated 90 degrees to the right. Applies to the calculation method vector. (Suppose the y-axis is pointing up, or turn left)
    • A.TURNRIGHT=VECTOR2F (a.y,-a.x);
    • vector2frotate (float angle): Rotates the vector by a specific angle. Although rarely found in vector classes, this is a very useful operation. is equivalent to multiplying by a 2x2 rotation matrix

A.rotate (angle) =vector2f (A.x*cos (angle)-a.y*sin (angle), a.x*sin (angle) +a.y*cos (angle));

    • Floatangle (): Returns the angle to which the vector is pointing.

A.angle () =atan2 (a.y,a.x);

A simple example-warm-up

Example of the distance between two points

You may know that you can use the Pythagorean theorem, but the vector method is simpler. Give direction A and vector B:

1

float distance = (A-B). Length ();

Example 2--straightening (alignment)

In some cases you may want to straighten it in the center of a picture. Sometimes you have to follow the upper-left or upper-middle points. More broadly, in order to maximize control of the straightening line, you can use a two-component, 0-to-1 (or even more, if you wish) vector to straighten in any direction.

1

2

Imgpos, imgsize and align is all vector2f

vector2f drawposition = imgpos + imgsize * Align

Example of 3--parametric linear equation

Two points define a line, but the definition has a lot of mystery. A good way to deal with a straight line is to use parametric equations: a point ("P0") and a direction ("dir").

1

2

vector2f p0 = point1;

vector2f dir = (point2-point1). unit ();

With this, you can, for example, you can get a distance p010 units far from the point:

1

vector2f P1 = p0 + dir * 10;

Example 4:--between midpoint and two points (interpolation)

Give directional quantities of p0 and P1. Their midpoint is (P0+P1)/2. More broadly, the segments defined by P0 and P1 can be changed by linear delay between 0 and 1.

1

vector2f p = (1-t) * p0 + t * p1;

In t=0, you get p0, you get P1 in T=1, you get the midpoint in t=0.5, and so on.

Example 5: Finding the normal direction of a segment

You already know how to find the direction of the line segment (example 3). Rotate it 90 degrees to get the normal vector, so use TurnLeft () or turnright () to get the result.

Using the projection of a point multiplication

The point multiplication is very helpful for calculating the length of the vector that is projected along One direction. We need a vector ("a") and a unit vector representing the projection direction ("dir") (So make sure you first use unit ()). Then the projection length is A.dot (dir). For example, if a= (3,4), dir= (1,0), then A.dot (dir) = 3. You can tell that this is correct, because (1,0) is the direction of the X axis. In fact a.x constant equals A.dot (vector2f (1,0)), A.Y constant equals A.dot (vector2f (0,1)).

Because the point multiplication of a and B can also be defined as |a| | B|cos (Alpha) (Alpha is a two-vector angle), so if both the vertical result is 0, if the two angle is less than 90 ° The result is positive, greater than 90 ° result is negative. We can use this to determine whether the two vectors point to the same general direction.

If you multiply the result of a point multiply by the direction vector, you get a projection of the vector along that direction-what we call "at" (t for tangential). If we do a-at, we will get a vector perpendicular to the direction vector-what we call "an" (N for normal). At+an=a.

Example 6--determines the direction closest to Dir

Suppose you have many unit vectors pointing in different directions, and you want to find out which direction is closest to Dir. Just find the one with the largest result in the list of vectors and the dir point multiply. Similarly, the smallest point multiplier means the furthest away.

Example 7--to determine if the angle of two vectors is less than alpha

Using the above equation, we know that if the point multiplication of the unit vectors of the two vectors A and B is less than the Cos (alpha), then the angle between them is less than alpha.

123 boolisLessThanAlpha(Vector2f a, Vector2f b, float alpha) {    returna.unit().dot(b.unit()) < cos(alpha);}

Example 8--judging the half plane of a point

Suppose there is any point in the plane p0, and a direction (unit) vector, dir. Suppose a wireless long line that crosses the p0, perpendicular to dir, divides the plane in two: dir points to the half plane and Dir does not point to a half plane. So how do you tell if a point P is on the side of Dir? Remember that when the angle between the vectors is less than 90 ° their point multiplication is positive, then just do the projection and then check:

123 boolisInsideHalfPlane(Vector2f p, Vector2f p0, Vector dir) {    return(p - p0).dot(dir) >= 0;}

Example 9--forcing a little in the half plane

Similar to the example above, but not just the check, if the projection is less than 0, we use it to move the target-projection to dir direction so that the target point is at the edge of the half plane.

12345 Vector2f makeInsideHalfPlane(Vector2f p, Vector2f p0, Vector dir) {    floatproj = (p - p0).dot(dir);    if (proj >= 0) return p;    else returnp - proj * dir;}

Example 10--Check/force a little in a convex multi-faceted body.

A convex multipatch can be defined as the result of intersecting multiple half-planes, with each intersection as the edge of the Multipatch. Their p0 are vertices on the edge, and their dir is the inner normal vector of the edge (for example, if you go clockwise, that is turnright () normal). A point is inside a multipatch if and only if it is within all half planes. Similarly, you can force it to use the Makeinsidehalfplane algorithm on all half planes in a multi-faceted body (by moving to the nearest edge). Oh It only works when all angles are >=90°]

Example 11--a vector reflected by a given normal

Play ball games, the ball hit a diagonal wall surface. The velocity vector of the known ball and the normal vector of the wall (see Example 5). How will it bounce in the real world? Simple! Simply reflect the normal velocity of the ball and keep its tangential velocity.

12345 Vector2f vel = getVel();Vector2f dir = getWallNormal(); // Make sure this is a unit vectorVector2f velN = dir * vel.dot(dir); // Normal componentVector2f velT = vel - velN; // Tangential componentVector2f reflectedVel = velT - velN;

To be closer to reality, you can multiply the Velt and veln by a constant that represents the friction and recovery coefficients respectively.

Example 12--offsets the movement along the axis

Sometimes we need to limit the movement to a given axis. The idea is the same as above: break the velocity down to normal and tangent upward, and then only the tangent speed is preserved. This helps to calculate the speed of people moving along the track.

Rotating

Example 13--points around a fixed point to do rotation

Assuming we have a little, rotate () rotates the point at the origin. It's fun, but there are limits. It is easy and practical to rotate at any point-just subtract the point by a dot, that is, pan the point to the origin, then rotate it, and then add the point back.

123 Vector2f rotateAroundPivot(Vector2f p, Vector2f pivot) {    return(pos - pivot).rotate(angle) + pivot;}

Example 14--determine which direction to rotate

Suppose we have a character who wants to turn toward the enemy. Known for his direction and direction toward the enemy. So should he turn left or right? Cross-multiplication gives a simple answer: Curdir.cross (targetDir) returns positive if you should turn left, negative if you should turn right (return 0 if you have already faced him or 180° back to him).

Additional Geometry examples

There are some other practical examples where vectors are not used too much, but are useful:

Example 15--offset space to screen coordinates

Equidistant game, you know where the world (0,0) is on the screen (let's call it the origin, use a vector to represent it), but how do you know where (x, y) is on the screen? First, you need two vectors representing the coordinate base, a new x-axis, and a new y-axis. For a typical isometric game, they can be bx=vector2f (2,1) and by=vector2f ( -2,1)-they are not necessarily unit vectors. Now, everything is simple.

12 Vector2f p = getWorldPoint();Vector2f screenPos = bx * p.x + by * p.y + origin;

Yes, it's very simple indeed.

Example 16--isometric screen to world coordinates

In the same situation, but this time you want to know which tile the mouse is sliding over. It's a little more complicated. We know (x ', y ') = (X*BX.X+Y*BY.X,X*BX.Y+Y*BY.Y) + origin, so we can subtract the origin first and then solve the equation. Using the Kramer rule, we can use the 2D cross-multiplication intelligently (to see the definition of the beginning of the article) to simplify:

12345 Vector2f pos = getMousePos() - origin;floatdemDet = bx.cross(by);float xDet = pos.cross(by);floatyDet = bx.cross(pos);Vector2f worldPos = Vector2f(xDet / demDet, yDet / demDet);

I think a lot of people are using the "Find rectangle and see Bitmap" method, and now you don't need it.

"Go" game Programmer's Mathematical food 05--vector quick look table

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.