DIRECTORY AdjustColor USING [NewGamma], AdjustColorStd USING [ByeProc, RegisterStdAdjuster, RequestControl, SetProc, Settings, TRC], PixelGraphics USING [Hermite, InterpolateLines, InterpolatePoints, InterpolateSpline, Point], Real USING [RoundLI], RealFns USING [Cos, Sin, Tan] ; TRCShapes: CEDAR PROGRAM IMPORTS AdjustColor, AdjustColorStd, PixelGraphics, Real, RealFns = BEGIN OPEN PG: PixelGraphics; Point: TYPE ~ PG.Point; Settings: TYPE ~ AdjustColorStd.Settings; TRC: TYPE ~ AdjustColorStd.TRC; p: REAL _ 3.141592653589793238462643383279; xSize, ySize: CARDINAL ~ 256; xMax: CARDINAL ~ xSize-1; yMax: CARDINAL ~ ySize-1; Gamma: AdjustColorStd.SetProc ~ { gamma: REAL ~ settings[contrast]*4.4; trc _ IF trc=NIL THEN NEW[TRC] ELSE old; FOR i: CARDINAL IN [0..256) DO trc[i] _ i; ENDLOOP; AdjustColor.NewGamma[gamma]; }; Linear: AdjustColorStd.SetProc ~ { PutInTRC: PROC [p: Point] ~ { trc[p.x] _ p.y; }; XY2UV: PROC [x, y: REAL] RETURNS [p: Point] ~ INLINE { p.x _ MAX[0, MIN[xMax, Real.RoundLI[x*xMax]]]; p.y _ MAX[0, MIN[yMax, Real.RoundLI[y*yMax]]]; }; m, b: REAL; --m and b for the equation y=mx+b. Note that x=(y-b)/m. points: LIST OF Point; trc _ IF trc=NIL THEN NEW[TRC] ELSE old; m _ RealFns.Tan[(p/2)*settings[contrast] ! ANY => {m_9999; CONTINUE}]; b _ 1-(m+1)*settings[dark]; SELECT m+b FROM --Does line hit right edge above or below square? > 1.0 => points _ LIST[XY2UV[(1-b)/m, 1], XY2UV[1, 1]]; --Above < 0.0 => points _ LIST[XY2UV[(-b)/m, 0], [1, 0]]; --Below ENDCASE => points _ LIST[ XY2UV[1, m+b] ]; SELECT b FROM --Does line hit left edge above or below square? > 1.0 => {points _ CONS[XY2UV[0, 1], CONS[XY2UV[(1-b)/m, 1], points]]}; < 0.0 => {points _ CONS[[0, 0], CONS[XY2UV[(-b)/m, 0], points]]}; ENDCASE => points _ CONS[XY2UV[0, b], points]; PG.InterpolateLines[points, PutInTRC]; }; vanMag: REAL _ 2.5; Spline: AdjustColorStd.SetProc ~ { PutInTRC: PROC [p: Point] ~ { trc[p.x] _ p.y; }; Squish: PROC [x, y: REAL] RETURNS [p: Point] ~ INLINE { RETURN [XY2UV[x: x*scale+black, y: y]]; }; ScaleVec: PROC [dx, dy: REAL] RETURNS [p: Point] ~ INLINE { RETURN [XY2UV[x: dx*scale, y: dy]]; }; XY2UV: PROC [x, y: REAL] RETURNS [p: Point] ~ INLINE { p.x _ MAX[0, MIN[xMax, Real.RoundLI[x*xMax]]]; p.y _ MAX[0, MIN[yMax, Real.RoundLI[y*yMax]]]; }; a, b: REAL; --Angles for Q1 and Q2 contrast: REAL _ settings[contrast]-0.5; dark: REAL _ settings[dark]-0.5; black: REAL _ settings[black]; white: REAL _ MAX[settings[white], black+0.01]; scale: REAL _ white-black; trc _ IF trc=NIL THEN NEW[TRC] ELSE old; a _ -MAX[MIN[contrast+dark, 0.5], -0.5]*p/2+p/4; b _ -MAX[MIN[contrast-dark, 0.5], -0.5]*p/2+p/4; PG.InterpolatePoints[XY2UV[0,0], Squish[0,0], PutInTRC]; PG.InterpolatePoints[Squish[1,1], XY2UV[1,1], PutInTRC]; PG.InterpolateSpline[ m: PG.Hermite[ p1: Squish[0, 0], p2: Squish[1, 1], q1: ScaleVec[vanMag*RealFns.Cos[a], vanMag*RealFns.Sin[a]], q2: ScaleVec[vanMag*RealFns.Cos[b], vanMag*RealFns.Sin[b]] ], segments: 20, proc: PutInTRC ]; }; ByeBye: AdjustColorStd.ByeProc ~ {}; Init: PROC ~ TRUSTED { AdjustColorStd.RegisterStdAdjuster[[ flavor: $Gamma, setProc: Gamma, byeProc: ByeBye ]]; AdjustColorStd.RegisterStdAdjuster[[ flavor: $Linear, setProc: Linear, byeProc: ByeBye ]]; AdjustColorStd.RegisterStdAdjuster[ adjuster: [ flavor: $Spline, setProc: Spline, byeProc: ByeBye ], initialSettings: [dark: 0.5, contrast: 0.5, black: 0.0, white: 1.0] ]; [] _ AdjustColorStd.RequestControl[$Gamma]; }; Init[]; END. HTRCShapes.mesa Copyright c 1985, Xerox Corporation. All rights reserved. Last edited by Eric Nickell, December 19, 1985 6:37:45 pm PST Control a simple line via Contrast and Darkness. The line has a slope which is a fcn of contrast. The darkness affects only the offset. If only the darkness is changed, the slope of the line remains unchanged. If only the contrast is changed, then the line will rotate about a point on the line which also lies on the line between the upper-left and lower-right corners. The basic idea is that we will use a single Hermite spline to model the TRC. The two control points on the ends (P1 and P2) will be set at the lower-left and upper-right corners respectively. Q1 and Q2, the tangents at the control points, are set to respond in parallel to contrast, and oppositely to darkness. Start-up Κ˜code™Kšœ Οmœ/™:K™=K™—šΟk ˜ Kšœ žœ ˜KšœžœCžœ˜\KšœžœJ˜]Kšœžœ ˜Kšœžœ˜J˜J˜—šœ žœž˜Kšžœ:˜AKšœž˜Kšžœžœ˜K˜Jšœžœžœ˜Jšœ žœ˜)Jšžœžœžœ˜J˜JšΟgœžœ$˜+J˜Jšœžœ˜Jšœžœ ˜Jšœžœ ˜J˜šΟnœ˜!Kšœžœ˜%Kš œžœžœžœžœžœžœ˜(šžœžœžœ ž˜K˜ Kšžœ˜—Kšœ˜Kšœ˜—code2š œ˜"J™φš œžœ˜Kšœ˜K˜—š  œžœžœžœžœ˜6Kšœžœžœ˜.Kšœžœžœ˜.K˜—KšœžœΟc7˜DJšœžœžœ˜J˜Kš œžœžœžœžœžœžœ˜(K˜JšœŸœžœ žœ˜FJšœ˜K˜šžœžœ‘1˜BKšœžœ"‘˜?Kšœžœ‘˜:Jšžœ žœ˜*—šžœžœ‘0˜?Kšœžœžœ˜GJšœžœ žœ˜AJšžœ žœ˜.—Jšžœ$˜&Jšœ˜J˜—Jšœžœ˜š œ˜"J™Έš œžœ˜Kšœ˜K˜—š  œžœžœžœžœ˜7Kšžœ!˜'K˜—š  œžœ žœžœžœ˜;Kšžœ˜#K˜—š  œžœžœžœžœ˜6Kšœžœžœ˜.Kšœžœžœ˜.K˜—KšŸœžœ‘˜$Jšœ žœ˜(Jšœžœ˜ Jšœžœ˜Jšœžœžœ˜/Jšœžœ˜J˜J˜Kš œžœžœžœžœžœžœ˜(K˜Jš ŸœžœžœŸœŸœ˜0Jš ŸœžœžœŸœŸœ˜0Jšžœ6˜8Kšžœ6˜8šžœ˜šœžœ ˜Jšœ˜Jšœ˜Kšœ ŸœŸœ˜;Kšœ ŸœŸœ˜:J˜—J˜ Jšœ˜J˜—Jšœ˜J˜—š œ˜$J˜—K˜Ititle™š œžœžœ˜˜$J˜Jšœ˜J˜J˜—˜$J˜Jšœ˜J˜J˜—˜#šœ ˜ J˜Jšœ˜J˜J˜—J˜CJ˜—K˜+J˜J˜—J˜K˜Kšžœ˜——…— †δ