DIRECTORY RealFns, GGBasicTypes, GGAngle, GGVector; GGVectorImpl: CEDAR PROGRAM IMPORTS RealFns, GGAngle EXPORTS GGVector = BEGIN Point: TYPE = GGBasicTypes.Point; Edge: TYPE = GGBasicTypes.Edge; Vector: TYPE = GGBasicTypes.Vector; VectorFromPoints: PUBLIC PROC [tail, head: Point] RETURNS [vector: Vector] = { vector.x _ head.x - tail.x; vector.y _ head.y - tail.y; }; VectorFromAngle: PUBLIC PROC [angle: REAL] RETURNS [vector: Vector] = { vector.x _ RealFns.CosDeg[angle]; vector.y _ RealFns.SinDeg[angle]; }; VectorPlusAngle: PUBLIC PROC [v: Vector, degrees: REAL] RETURNS [rotatedV: Vector] = { theta: REAL _ RealFns.ArcTanDeg[v.y, v.x]; angleSum: REAL _ theta + degrees; IF angleSum<= -180 THEN angleSum _ angleSum + 360 ELSE IF angleSum > 180 THEN angleSum _ angleSum - 360; rotatedV _ VectorFromAngle[angleSum]; }; AngleFromVector: PUBLIC PROC [v: Vector] RETURNS [position: REAL] = { position _ GGAngle.ArcTan[v.y, v.x]; }; AngleCCWBetweenVectors: PUBLIC PROC [v1, v2: Vector] RETURNS [difference: REAL] = { angle1, angle2: REAL; angle1 _ AngleFromVector[v1]; angle2 _ AngleFromVector[v2]; difference _ GGAngle.CounterClockwiseAngle[angle1, angle2]; }; AngleCWBetweenVectors: PUBLIC PROC [v1, v2: Vector] RETURNS [difference: REAL] = { angle1, angle2: REAL; angle1 _ AngleFromVector[v1]; angle2 _ AngleFromVector[v2]; difference _ GGAngle.ClockwiseAngle[angle1, angle2]; }; SmallestAngleBetweenVectors: PUBLIC PROC [v1, v2: Vector] RETURNS [difference: REAL] = { angle1, angle2: REAL; angle1 _ AngleFromVector[v1]; angle2 _ AngleFromVector[v2]; difference _ GGAngle.ShortestDifference[angle1, angle2]; }; Add: PUBLIC PROC [v1, v2: Vector] RETURNS [v1PlusV2: Vector] = { v1PlusV2.x _ v1.x + v2.x; v1PlusV2.y _ v1.y + v2.y; }; Sub: PUBLIC PROC [v1, v2: Vector] RETURNS [v1MinusV2: Vector] = { v1MinusV2.x _ v1.x - v2.x; v1MinusV2.y _ v1.y - v2.y; }; Scale: PUBLIC PROC[v: Vector, s: REAL] RETURNS [vTimesS: Vector] = { vTimesS.x _ v.x*s; vTimesS.y _ v.y*s; }; Normalize: PUBLIC PROC [v: Vector] RETURNS [normV: Vector] = { mag: REAL _ Magnitude[v]; normV.x _ v.x / mag; normV.y _ v.y /mag; }; Negate: PUBLIC PROC [v: Vector] RETURNS [negV: Vector] = { negV.x _ -v.x; negV.y _ -v.y; }; ElementwiseProduct: PUBLIC PROC [v1, v2: Vector] RETURNS [v1Timesv2: Vector] = { v1Timesv2.x _ v1.x*v2.x; v1Timesv2.y _ v1.y*v2.y; }; DotProduct: PUBLIC PROC [v1, v2: Vector] RETURNS [scalar: REAL] = { scalar _ v1.x*v2.x + v1.y*v2.y; }; CrossProductScalar: PUBLIC PROC [v1, v2: Vector] RETURNS [scalar: REAL] = { scalar _ v1.x*v2.y - v1.y*v2.x; }; Magnitude: PUBLIC PROC [v: Vector] RETURNS [mag: REAL] = { mag _ RealFns.SqRt[v.x*v.x + v.y*v.y]; }; Distance: PUBLIC PROC [p1, p2: Point] RETURNS [dist: REAL] = { dist _ Magnitude[Sub[p2, p1]]; }; MagnitudeSquared: PUBLIC PROC [v: Vector] RETURNS [magSquared: REAL] = { magSquared _ v.x*v.x + v.y*v.y; }; DistanceSquared: PUBLIC PROC [p1, p2: Point] RETURNS [distSquared: REAL] = { distSquared _ MagnitudeSquared[Sub[p2, p1]]; }; RightNormalOfEdge: PUBLIC PROC [edge: Edge] RETURNS [normal: Vector] = { direction: Vector; IF edge.startIsFirst THEN direction _ VectorFromPoints[tail: edge.start, head: edge.end] ELSE direction _ VectorFromPoints[tail: edge.end, head: edge.start]; normal.x _ direction.y; normal.y _ -direction.x; }; LeftNormalOfEdge: PUBLIC PROC [edge: Edge] RETURNS [normal: Vector] = { direction: Vector; IF edge.startIsFirst THEN direction _ VectorFromPoints[tail: edge.start, head: edge.end] ELSE direction _ VectorFromPoints[tail: edge.end, head: edge.start]; normal.x _ -direction.y; normal.y _ direction.x; }; END. ŽFile: GGVectorImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last edited by Bier on June 4, 1985 6:11:29 pm PDT Author: Eric Bier on July 31, 1986 10:28:35 pm PDT Contents: Routines for manipulation vectors in two dimensions Pier, May 30, 1986 5:04:23 pm PDT angle must be in degrees in the range: -180 < angle <= 180. vector is a unit vector. Find angle of v. This should be easy. Normalize v and its components will be cos(theta), sin(theta) respectively. position is a position angle such that -180 < position <= 180 difference will be in: 0 <= difference < 360. A clockwise angle difference will be in: 0 <= difference < 360. A counter-clockwise angle all angles in degrees. RETURNS ClockwiseAngle or CounterClockwiseAngle. Whichever is smaller. -180 < difference <= 180. Given the ordered points of the line segment, we can find the vector from the first to the second. If this vector is [a, b] then the vector 90 degrees to the right is [b, -a]; Given the ordered points of the line segment, we can find the vector from the first to the second. If this vector is [a, b] then the vector 90 degrees to the left is [-b, a]; Κu˜codešœ™Kšœ Οmœ1™Kšœžœ˜Kšœ˜Kšœ˜Kšœ˜K˜—šŸœžœžœ žœ˜:Kšœ˜Kšœ˜K˜K˜—šŸœžœžœžœ˜PKšœ˜Kšœ˜Kšœ˜K˜—š Ÿ œžœžœžœ žœ˜CKšœ˜Kšœ˜K˜—š Ÿœžœžœžœ žœ˜KKšœ˜Kšœ˜K˜—š Ÿ œžœžœžœžœ˜;Kšœ&˜&Kšœ˜K˜—š Ÿœžœžœžœžœ˜>Kšœ˜K˜K˜—š Ÿœžœžœ žœžœ˜HKšœ˜Kšœ˜K˜—š Ÿœžœžœžœžœ˜LKšœ,˜,K˜—K˜šŸœžœžœžœ˜HKšœ°™°Kšœ˜Kšžœžœ@˜YKšžœA˜EKšœ˜Kšœ˜Kšœ˜K˜—šŸœžœžœžœ˜GKšœ―™―Kšœ˜Kšžœžœ@˜YKšžœA˜EKšœ˜Kšœ˜Kšœ˜—K˜Kšžœ˜K˜—…—