DIRECTORY G3dBasic, G3dPlane, G3dVector, ImplicitDefs, ImplicitValue, RealFns; ImplicitValueImpl: CEDAR MONITOR IMPORTS G3dPlane, G3dVector, RealFns EXPORTS ImplicitValue ~ BEGIN Pair: TYPE ~ G3dBasic.Pair; Triple: TYPE ~ G3dBasic.Triple; TripleSequence: TYPE ~ G3dBasic.TripleSequence; TripleSequenceRep: TYPE ~ G3dBasic.TripleSequenceRep; Plane: TYPE ~ G3dPlane.Plane; NearSegment: TYPE ~ G3dVector.NearSegment; DistanceMode: TYPE ~ ImplicitDefs.DistanceMode; Sample: TYPE ~ ImplicitDefs.Sample; Source2d: TYPE ~ ImplicitValue.Source2d; Source2dSequence: TYPE ~ ImplicitValue.Source2dSequence; Source2dSequenceRep: TYPE ~ ImplicitValue.Source2dSequenceRep; Source3d: TYPE ~ ImplicitValue.Source3d; Source3dSequence: TYPE ~ ImplicitValue.Source3dSequence; Source3dSequenceRep: TYPE ~ ImplicitValue.Source3dSequenceRep; ValueProc: TYPE ~ ImplicitValue.ValueProc; SqDist3d: PROC [i, j: Triple] RETURNS [REAL] ~ { d: Triple ~ [j.x-i.x, j.y-i.y, j.z-i.z]; RETURN[d.x*d.x+d.y*d.y+d.z*d.z]; }; Dist3d: PROC [i, j: Triple] RETURNS [REAL] ~ { d: Triple ~ [j.x-i.x, j.y-i.y, j.z-i.z]; RETURN[RealFns.SqRt[d.x*d.x+d.y*d.y+d.z*d.z]]; }; SqDist2d: PROC [i, j: Pair] RETURNS [REAL] ~ { d: Pair ~ [j.x-i.x, j.y-i.y]; RETURN[d.x*d.x+d.y*d.y]; }; Dist2d: PROC [i, j: Pair] RETURNS [REAL] ~ { d: Pair ~ [j.x-i.x, j.y-i.y]; RETURN[RealFns.SqRt[d.x*d.x+d.y*d.y]]; }; OfPoint: PUBLIC PROC [ q, source: Triple, strength: REAL, distanceMode: DistanceMode] RETURNS [sample: Sample] ~ { sample.near ¬ source; sample.vector ¬ [source.x-q.x, source.y-q.y, source.z-q.z]; sample.squareDistance ¬ sample.vector.x*sample.vector.x+sample.vector.y*sample.vector.y+ sample.vector.z*sample.vector.z; SELECT distanceMode FROM inverse, wtInverse => { sample.distance ¬ RealFns.SqRt[sample.squareDistance]; sample.distanceSet ¬ TRUE; sample.value ¬ strength/MAX[0.0001, sample.distance]; }; inverseSqrd, wtInverseSqrd => sample.value ¬ strength*strength/MAX[0.0001, sample.squareDistance]; ENDCASE; }; CombineSamples: PUBLIC PROC [samples: LIST OF Sample] RETURNS [sample: Sample] ~ { value: REAL ¬ 0.0; FOR s: LIST OF Sample ¬ samples, s.rest WHILE s # NIL DO IF s.first.value > sample.value THEN sample ¬ s.first; value ¬ value+s.first.value; ENDLOOP; sample.value ¬ value; }; nScratchSourcer2d: NAT ~ 6; nScratchSources3d: NAT ~ 6; scratchSourcer2d: ARRAY [0..nScratchSourcer2d) OF Source2dSequence ¬ ALL[NIL]; scratchSources3d: ARRAY [0..nScratchSources3d) OF Source3dSequence ¬ ALL[NIL]; ObtainSources2d: PUBLIC ENTRY PROC [nSources: NAT] RETURNS [Source2dSequence] ~ { FOR i: NAT IN [0..nScratchSourcer2d) DO sources: Source2dSequence ¬ scratchSourcer2d[i]; IF sources # NIL THEN { scratchSourcer2d[i] ¬ NIL; IF sources.maxLength < nSources THEN sources ¬ NEW[Source2dSequenceRep[nSources]]; RETURN [sources]; }; ENDLOOP; RETURN[NEW[Source2dSequenceRep[nSources]]]; }; ObtainSources3d: PUBLIC ENTRY PROC [nSources: NAT] RETURNS [Source3dSequence] ~ { FOR i: NAT IN [0..nScratchSources3d) DO sources: Source3dSequence ¬ scratchSources3d[i]; IF sources # NIL THEN { scratchSources3d[i] ¬ NIL; IF sources.maxLength < nSources THEN sources ¬ NEW[Source3dSequenceRep[nSources]]; RETURN [sources]; }; ENDLOOP; RETURN[NEW[Source3dSequenceRep[nSources]]]; }; ReleaseSources2d: PUBLIC ENTRY PROC [sources: Source2dSequence] ~ { FOR i: NAT IN [0..nScratchSourcer2d) DO IF scratchSourcer2d[i] = NIL THEN { scratchSourcer2d[i] ¬ sources; RETURN; }; ENDLOOP; }; ReleaseSources3d: PUBLIC ENTRY PROC [sources: Source3dSequence] ~ { FOR i: NAT IN [0..nScratchSources3d) DO IF scratchSources3d[i] = NIL THEN { scratchSources3d[i] ¬ sources; RETURN; }; ENDLOOP; }; WtFunction: TYPE ~ PROC [strength, sqDist, dist: REAL] RETURNS [val: REAL]; OfSources2d: PUBLIC PROC [ q: Pair, sources: Source2dSequence, distanceMode: DistanceMode] RETURNS [sum: REAL ¬ 0.0] ~ { Inverse: PROC ~ { FOR n: NAT IN [0..sources.length) DO s: Source2d ~ sources[n]; sum ¬ sum+s.strength/MAX[0.0001, Dist2d[s.p, q]]; ENDLOOP; }; InverseSquared: PROC ~ { FOR n: NAT IN [0..sources.length) DO s: Source2d ~ sources[n]; sum ¬ sum+s.strength*s.strength/MAX[0.0001, SqDist2d[s.p, q]]; ENDLOOP; }; Wt: PROC [f: WtFunction] ~ { info: TripleSequence ¬ NEW[TripleSequenceRep[sources.length]]; -- [sqDist, dist, val] FOR i: NAT IN [0..sources.length) DO info[i].y ¬ RealFns.SqRt[info[i].x ¬ SqDist2d[sources[i].p, q]]; info[i].z ¬ f[sources[i].strength, info[i].x, info[i].y]; ENDLOOP; FOR n: NAT IN [0..sources.length) DO FOR nn: NAT IN [n+1..sources.length) DO d: REAL ~ Dist2d[sources[n].p, sources[nn].p]; sum ¬ sum+(d/(info[n].y+info[nn].y))*(info[n].z+info[nn].z); ENDLOOP; ENDLOOP; }; WtInverse: PROC ~ { F: WtFunction ~ {val ¬ strength/MAX[0.0001, sqDist]}; Wt[F]; }; WtInvSq: PROC ~ { F: WtFunction ~ {val ¬ strength*strength/MAX[0.0001, dist]}; Wt[F]; }; SELECT distanceMode FROM inverse => Inverse[]; inverseSqrd => InverseSquared[]; wtInverse => IF sources.length = 1 THEN Inverse[] ELSE WtInverse[]; wtInverseSqrd => IF sources.length = 1 THEN InverseSquared[] ELSE WtInvSq[]; ENDCASE; }; OfSources3d: PUBLIC PROC [ q: Triple, sources: Source3dSequence, distanceMode: DistanceMode] RETURNS [sum: REAL ¬ 0.0] ~ { Inverse: PROC ~ { FOR n: NAT IN [0..sources.length) DO s: Source3d ~ sources[n]; sum ¬ sum+s.strength/MAX[0.0001, Dist3d[s.p, q]]; ENDLOOP; }; InverseSquared: PROC ~ { FOR n: NAT IN [0..sources.length) DO s: Source3d ~ sources[n]; sum ¬ sum+s.strength*s.strength/MAX[0.0001, SqDist3d[s.p, q]]; ENDLOOP; }; Wt: PROC [f: WtFunction] ~ { info: TripleSequence ¬ NEW[TripleSequenceRep[sources.length]]; -- [sqDist, dist, val] FOR i: NAT IN [0..sources.length) DO info[i].y ¬ RealFns.SqRt[info[i].x ¬ SqDist3d[sources[i].p, q]]; info[i].z ¬ f[sources[i].strength, info[i].x, info[i].y]; ENDLOOP; FOR n: NAT IN [0..sources.length) DO FOR nn: NAT IN [n+1..sources.length) DO d: REAL ~ Dist3d[sources[n].p, sources[nn].p]; sum ¬ sum+(d/(info[n].y+info[nn].y))*(info[n].z+info[nn].z); ENDLOOP; ENDLOOP; }; WtInverse: PROC ~ { F: WtFunction ~ {val ¬ strength/MAX[0.0001, sqDist]}; Wt[F]; }; WtInvSq: PROC ~ { F: WtFunction ~ {val ¬ strength*strength/MAX[0.0001, dist]}; Wt[F]; }; SELECT distanceMode FROM inverse => Inverse[]; inverseSqrd => InverseSquared[]; wtInverse => IF sources.length = 1 THEN Inverse[] ELSE WtInverse[]; wtInverseSqrd => IF sources.length = 1 THEN InverseSquared[] ELSE WtInvSq[]; ENDCASE; }; OfPlane: PUBLIC PROC [q: Triple, plane: Plane] RETURNS [sample: Sample] ~ { sample.distance ¬ G3dPlane.DistanceToPoint[q, plane]; sample.distanceSet ¬ TRUE; sample.squareDistance ¬ sample.distance*sample.distance; }; OfSphere: PUBLIC PROC [q, center: Triple, radiusSqd: REAL] RETURNS [sample: Sample] ~ { sample.near ¬ center; sample.squareDistance ¬ G3dVector.SquareDistance[center, q]; sample.value ¬ radiusSqd*sample.squareDistance; }; OfCylinder: PUBLIC PROC [q: Triple, end0, end1: Triple, radiusSqd: REAL] RETURNS [sample: Sample] ~ { n: NearSegment ~ G3dVector.NearestToSegment[end0, end1, q]; sample.near ¬ n.point; sample.squareDistance ¬ G3dVector.SquareDistance[q, sample.near]; sample.value ¬ radiusSqd*sample.squareDistance; }; OfTorus: PUBLIC PROC [q: Triple, minorRadius, majorRadius: REAL] RETURNS [sample: Sample] ~ { r2: REAL ~ majorRadius*majorRadius; rr2: REAL ~ minorRadius*minorRadius; r4: REAL ~ r2*r2; rr4: REAL ~ rr2*rr2; a: REAL ~ r2+rr2; b: REAL ~ r2-rr2; c: REAL ~ r2*rr2; t: Triple ~ G3dVector.MulVectors[q, q]; sample.value ¬ t.x*t.x+t.y*t.y+t.z*t.z+r4+rr4+2.0*(t.x*t.y+t.x*t.z+t.y*t.z-a*t.x+b*t.y-a*t.z-c); }; END. .. OfSources2d: PUBLIC PROC [ q: Pair, sources: Source2dSequence, distanceMode: DistanceMode, threshold: REAL ¬ 1.0] RETURNS [sum: REAL ¬ 0.0] ~ { Inverse: PROC ~ { FOR n: NAT IN [0..sources.length) DO s: Source2d ~ sources[n]; sum ¬ sum+s.strength*threshold/MAX[0.0001, Dist2d[s.p, q]]; ENDLOOP; }; InvSq: PROC ~ { FOR n: NAT IN [0..sources.length) DO s: Source2d ~ sources[n]; sum ¬ sum+s.strength*s.strength*threshold/MAX[0.0001, SqDist2d[s.p, q]]; ENDLOOP; }; Wt: PROC [f: WtFunction] ~ { info: TripleSequence ¬ NEW[TripleSequenceRep[sources.length]]; -- [sqDist, dist, val] FOR i: NAT IN [0..sources.length) DO info[i].y ¬ RealFns.SqRt[info[i].x ¬ SqDist2d[sources[i].p, q]]; info[i].z ¬ f[sources[i].strength, info[i].x, info[i].y]; ENDLOOP; FOR n: NAT IN [0..sources.length) DO FOR nn: NAT IN [n+1..sources.length) DO d: REAL ~ Dist2d[sources[n].p, sources[nn].p]; sum ¬ sum+(d/(info[n].y+info[nn].y))*(info[n].z+info[nn].z); ENDLOOP; ENDLOOP; }; WtInverse: PROC ~ { F: WtFunction ~ {val ¬ strength*threshold/MAX[0.0001, sqDist]}; Wt[F]; }; WtInvSq: PROC ~ { F: WtFunction ~ {val ¬ strength*strength*threshold/MAX[0.0001, dist]}; Wt[F]; }; SELECT distanceMode FROM inverse => Inverse[]; invSq => InvSq[]; wtInverse => IF sources.length = 1 THEN Inverse[] ELSE WtInverse[]; wtInvSq => IF sources.length = 1 THEN InvSq[] ELSE WtInvSq[]; ENDCASE; }; OfMesh: PUBLIC PROC [ q: Triple, mesh: Mesh, distanceMode: DistanceMode, threshold: REAL ¬ 1.0] RETURNS [sample: Sample] ~ { s: SegmentSequence ~ mesh.segments; t: TriangleSequence ~ mesh.triangles; p: PolygonSequence ~ mesh.polygons; temp: Sample; sInside: Sample ¬ OfInsideSegments[q, s, distanceMode, threshold]; tInside: Sample ¬ OfInsideTriangles[q, t, distanceMode, threshold]; pInside: Sample ¬ OfInsidePolygons[q, p, distanceMode, threshold]; SELECT TRUE FROM sInside.value = 0.0 AND tInside.value = 0.0 AND pInside.value = 0.0 => { temp ¬ OfEdgeSegments[q, s, distanceMode, threshold]; IF temp.value > sample.value THEN sample ¬ temp; temp ¬ OfEdgeTriangles[q, t, distanceMode, threshold]; IF temp.value > sample.value THEN sample ¬ temp; temp ¬ OfEdgePolygons[q, p, distanceMode, threshold]; IF temp.value > sample.value THEN sample ¬ temp; }; tInside.value = 0.0 AND pInside.value = 0.0 => { sample ¬ sInside; temp ¬ OfEdgeTriangles[q, t, distanceMode, threshold]; IF temp.value > sample.value THEN sample ¬ temp; temp ¬ OfEdgePolygons[q, p, distanceMode, threshold]; IF temp.value > sample.value THEN sample ¬ temp; }; ENDCASE => { sample ¬ sInside; IF tInside.value > sample.value THEN sample ¬ tInside; IF pInside.value > sample.value THEN sample ¬ pInside; sample.value ¬ sInside.value+tInside.value+pInside.value; }; }; nScratchItemSequences: NAT ~ 10; scratchItemSequences: ARRAY [0..nScratchItemSequences) OF ItemSequence ¬ ALL[NIL]; ObtainItems: ENTRY PROC [nItems: NAT] RETURNS [ItemSequence] ~ { IF nItems = 0 THEN RETURN[NIL]; FOR i: NAT IN [0..nScratchItemSequences) DO items: ItemSequence ¬ scratchItemSequences[i]; IF items = NIL THEN LOOP; scratchItemSequences[i] ¬ NIL; IF items.maxLength < nItems THEN items ¬ NEW[ItemSequenceRep[nItems]]; items.length ¬ 0; RETURN [items]; ENDLOOP; RETURN[NEW[ItemSequenceRep[nItems]]]; }; ReleaseItems: ENTRY PROC [items: ItemSequence] ~ { FOR i: NAT IN [0..nScratchItemSequences) DO IF scratchItemSequences[i] # NIL THEN LOOP; scratchItemSequences[i] ¬ items; RETURN; ENDLOOP; }; NItems: PROC [mesh: Mesh] RETURNS [n: NAT ¬ 0] ~ { IF mesh = NIL THEN RETURN; IF mesh.segments # NIL THEN n ¬ n+mesh.segments.length; IF mesh.triangles # NIL THEN n ¬ n+mesh.triangles.length; IF mesh.polygons # NIL THEN n ¬ n+mesh.polygons.length; }; TriangleStrength: PROC [triangle: Triangle, near: NearTriangle] RETURNS [REAL] ~ { RETURN[ (triangle.s0*near.w0+triangle.s1*near.w1+triangle.s2*near.w2)/(near.w0+near.w1+near.w2)]; }; DoItems: PROC [ q: Triple, mesh: Mesh, distanceMode: DistanceMode, segmentScale: REAL ¬ 1.0, triangleScale: REAL ¬ 1.0, threshold: REAL ¬ 1.0] RETURNS [items: ItemSequence] ~ { AddToItemSequence: PROC [item: Item, scale: REAL] ~ { item.sample.value ¬ item.sample.value*scale; items[items.length] ¬ item; items.length ¬ items.length+1; }; IF (items ¬ ObtainItems[NItems[mesh]]) = NIL THEN RETURN; IF mesh.triangles # NIL THEN FOR n: NAT IN [0..mesh.triangles.length) DO triangle: Triangle ~ mesh.triangles[n]; near: NearTriangle ~ G3dPolygon.NearestToTriangle[triangle, q]; sample: Sample ¬ IF near.inside THEN ImplicitValue.OfPoint[ q, near.point, TriangleStrength[triangle, near], distanceMode, threshold] ELSE ImplicitValue.OfTriangleEdges[q, triangle, distanceMode, threshold]; AddToItemSequence[[sample, near.inside, tripoly], triangleScale]; ENDLOOP; IF mesh.polygons # NIL THEN FOR n: NAT IN [0..mesh.polygons.length) DO polygon: Polygon ~ mesh.polygons[n]; near: NearPolygon ~ G3dPolygon.NearestToPolygon[polygon, q]; sample: Sample ¬ IF near.inside THEN ImplicitValue.OfPoint[ q, near.point, ImplicitValue.PolygonStrength[polygon, q], distanceMode, threshold] ELSE ImplicitValue.OfPolygonEdges[q, polygon, distanceMode, threshold]; AddToItemSequence[[sample, near.inside, tripoly], triangleScale]; ENDLOOP; IF mesh.segments # NIL THEN FOR n: NAT IN [0..mesh.segments.length) DO seg: Segment3d ~ mesh.segments[n]; near: NearSegment ~ G3dVector.NearestTo3dSegment[seg.p0, seg.p1, q, seg.acc]; sample: Sample ¬ ImplicitValue.OfPoint[ q, near.point, seg.s0*near.w0+seg.s1*near.w1, distanceMode, threshold]; AddToItemSequence[[sample, near.inside, segment], segmentScale]; ENDLOOP; }; MaxItem: PROC [items: ItemSequence] RETURNS [index: INTEGER ¬ -1] ~ { max: REAL ¬ -100000.0; IF items # NIL THEN FOR n: NAT IN [0..items.length) DO IF items[n].sample.value > max THEN {max ¬ items[n].sample.value; index ¬ n}; ENDLOOP; }; MaxSegmentItem: PROC [items: ItemSequence] RETURNS [index: INTEGER ¬ -1] ~ { max: REAL ¬ -100000.0; IF items # NIL THEN FOR n: NAT IN [0..items.length) DO i: Item ¬ items[n]; IF i.type = segment AND i.sample.value > max THEN {max ¬ i.sample.value; index ¬ n}; ENDLOOP; }; MaxTripolyItem: PROC [items: ItemSequence] RETURNS [index: INTEGER ¬ -1] ~ { max: REAL ¬ -100000.0; IF items # NIL THEN FOR n: NAT IN [0..items.length) DO i: Item ¬ items[n]; IF i.type = tripoly AND i.sample.value > max THEN {max ¬ i.sample.value; index ¬ n}; ENDLOOP; }; SimpleValue: PROC [ q: Triple, mesh: Mesh, distanceMode: DistanceMode, segmentScale: REAL ¬ 1.0, triangleScale: REAL ¬ 1.0, threshold: REAL ¬ 1.0] RETURNS [sample: Sample] ~ { items: ItemSequence ¬ DoItems[q, mesh, distanceMode, segmentScale, triangleScale, threshold]; IF items # NIL THEN { Sum: PROC [n: INTEGER, v: Triple] RETURNS [REAL ¬ 0.0] ~ { s: Sample ¬ items[n].sample; l: REAL ¬ IF s.distanceSet THEN s.distance ELSE RealFns.SqRt[s.squareDistance]; IF l # 0.0 THEN { acos: REAL ¬ (v.x*s.vector.x+v.y*s.vector.y+v.z*s.vector.z)/l; RETURN[0.5*(1.0-acos)*s.value]; }; }; SumSegments: PROC RETURNS [sample: Sample] ~ { nMax: NAT ¬ MaxSegmentItem[items]; max: Item ¬ items[nMax]; sample ¬ max.sample; IF mesh.segments.length = 1 THEN RETURN[max.sample] ELSE { v: Triple ¬ G3dVector.Normalize[max.sample.vector]; FOR n: NAT IN [0..items.length) DO IF n # nMax AND items[n].type = segment AND items[n].inside THEN sample.value ¬ sample.value+Sum[n, v]; ENDLOOP; }; }; SumTripolys: PROC RETURNS [sample: Sample] ~ { nTripolys: INTEGER ¬ (IF mesh.triangles = NIL THEN 0 ELSE mesh.triangles.length)+ (IF mesh.polygons = NIL THEN 0 ELSE mesh.polygons.length); nMax: NAT ¬ MaxTripolyItem[items]; max: Item ¬ items[nMax]; sample ¬ max.sample; IF nTripolys = 1 THEN RETURN[max.sample] ELSE { v: Triple ¬ G3dVector.Normalize[max.sample.vector]; FOR n: NAT IN [0..items.length) DO IF n # nMax AND items[n].type = tripoly AND items[n].inside THEN sample.value ¬ sample.value+Sum[n, v]; ENDLOOP; }; }; SELECT TRUE FROM mesh.segments = NIL => RETURN[SumTripolys[]]; mesh.triangles = NIL AND mesh.polygons = NIL => RETURN[SumSegments[]]; ENDCASE => { sSample: Sample ¬ SumSegments[]; tSample: Sample ¬ SumTripolys[]; sample ¬ IF sSample.value > tSample.value THEN sSample ELSE tSample; sample.value ¬ sSample.value+tSample.value; }; }; ReleaseItems[items]; }; CleverValue: PROC [ q: Triple, mesh: Mesh, distanceMode: DistanceMode, segmentScale: REAL ¬ 1.0, triangleScale: REAL ¬ 1.0, threshold: REAL ¬ 1.0] RETURNS [sample: Sample] ~ { items: ItemSequence ¬ DoItems[q, mesh, distanceMode, segmentScale, triangleScale, threshold]; sample ¬ DoClever[q, items, distanceMode, threshold]; ReleaseItems[items]; }; CleverValueDebug: PROC [ q: Triple, mesh: Mesh, distanceMode: DistanceMode, segmentScale: REAL ¬ 1.0, triangleScale: REAL ¬ 1.0, threshold: REAL ¬ 1.0] RETURNS [sample: Sample, items: ItemSequence] ~ { items ¬ DoItems[q, mesh, distanceMode, segmentScale, triangleScale, threshold]; sample ¬ DoClever[q, items, distanceMode, threshold]; }; DoClever: PROC [ q: Triple, items: ItemSequence, distanceMode: DistanceMode, threshold: REAL] RETURNS [sample: Sample] ~ { IF items # NIL THEN { Sum: PROC [n: INTEGER] ~ { IF n # -1 THEN { s: Sample ¬ items[n].sample; l: REAL ¬ IF s.distanceSet THEN s.distance ELSE RealFns.SqRt[s.squareDistance]; IF l # 0.0 THEN { acos: REAL ¬ G3dVector.Dot[v, s.vector]/l; sample.value ¬ sample.value+0.5*(1.0-acos)*s.value; }; }; }; nMax: NAT ¬ MaxItem[items]; max: Item ¬ items[nMax]; v: Triple ¬ G3dVector.Normalize[max.sample.vector]; sample ¬ max.sample; SELECT max.type FROM segment => { FOR n: NAT IN [0..items.length) DO IF n # nMax AND items[n].inside AND items[n].type = segment THEN Sum[n]; ENDLOOP; Sum[MaxTripolyItem[items]]; }; tripoly => IF max.inside THEN { FOR n: NAT IN [0..items.length) DO IF n # nMax AND items[n].inside AND items[n].type = tripoly THEN Sum[n]; ENDLOOP; Sum[MaxSegmentItem[items]]; } ELSE { someInsideSegments: BOOL ¬ FALSE; FOR n: NAT IN [0..items.length) DO IF items[n].type # segment OR NOT items[n].inside THEN LOOP; someInsideSegments ¬ TRUE; Sum[n]; ENDLOOP; IF NOT someInsideSegments THEN Sum[MaxSegmentItem[items]]; }; ENDCASE; }; }; € ImplicitValueImpl.mesa Copyright Σ 1985, 1990 by Xerox Corporation. All rights reserved. Bloomenthal, November 21, 1992 7:00 pm PST Support Point and Line Segment Sources Miscellany SourceSequences Simple Geometric Shapes Notes: an inside value is derived from the length of a perpendicular dropped to a primitive; in the case of a segment, this is a perpendicular to the line containing the segment, in the case of triangles and polygons, it is a perpendicular dropped to the plane containing the triangle or polygon. If the intersection of perpendicular with line (plane) does not lie within the segment (triangle or polygon) distance to the closest segment endpoint (triangle or polygon edge) is used to compute a value. Nothing registers inside, so find closest edge: A segment registers inside, so add in closest edge of triangles and polygons: Skirt Inside or edge, whichever max ΚW•NewlineDelimiter ™™JšœB™BJ™*J˜JšΟk œE˜NJ˜—šΠblœœ˜ Jšœ˜$Jšœ˜J˜—šœ˜J˜Jšœ œ˜ Jšœœ˜#Jšœœ˜1Jšœœ˜6Jšœ œ˜"Jšœ œ˜,Jšœœ˜1Jšœœ˜'Jšœ œ˜,Jšœœ"˜9Jšœœ%˜>Jšœ œ˜,Jšœœ"˜9Jšœœ%˜>Jšœ œ˜-—headšΟl™šΟnœœœœ˜0J˜(Jšœ˜ J˜J˜—š œœœœ˜.J˜(Jšœ(˜.J˜J˜—š œœœœ˜.J˜Jšœ˜J˜J˜—š œœœœ˜,J˜Jšœ ˜&J˜——šŸ™š œ œ˜J˜Jšœ œ˜Jšœ˜Jšœ˜J˜J˜J˜;˜J˜@J˜ —šœ˜˜J˜6Jšœœ˜Jšœœ˜5J˜—šœ˜Jšœ!œ ˜D—Jšœ˜—J˜——šŸ ™ š  œœœ œœ œ˜RJšœœ˜š œœœœœ˜8Jšœœ˜6J˜Jšœ˜—J˜J˜——šŸ™Icodešœœ˜Lšœœ˜Lš œœœœœ˜Nš œœœœœ˜NL˜—š  œœœœ œœ˜Qšœœœ˜'L˜0šœ œœ˜Lšœœ˜Lšœœ œ ˜RLšœ ˜L˜—Lšœ˜—Lšœœ!˜+L˜L˜—š  œœœœ œœ˜Qšœœœ˜'L˜0šœ œœ˜Lšœœ˜Lšœœ œ ˜RLšœ ˜L˜—Lšœ˜—Lšœœ!˜+L˜L˜—š œœœœ ˜Cšœœœ˜'šœœœ˜#J˜Jšœ˜J˜—Lšœ˜—L˜L˜—š œœœœ ˜Cšœœœ˜'šœœœ˜#J˜Jšœ˜J˜—Lšœ˜—L˜L˜—š œ œœœœœ˜KJ˜—š  œ œ˜J˜J˜Jšœ˜Jšœœ˜J˜š œœ˜šœœœ˜$J˜Jšœœ˜1Jšœ˜—J˜—š œœ˜šœœœ˜$J˜Jšœ œ˜>Jšœ˜—J˜—š œœ˜Jšœœ%Οc˜Ušœœœ˜$J˜@J˜9Jšœ˜—šœœœ˜$šœœœ˜'Jšœœ'˜.J˜Jšœ˜—J˜—š œœ˜Jšœœ%‘˜Ušœœœ˜$J˜@J˜9Jšœ˜—šœœœ˜$šœœœ˜'Jšœœ'˜.J˜Jšœ˜—J˜J˜—š œ œ˜J˜ J˜ J˜Jšœ œ˜Jšœ˜J˜J™\J™\J™YJ™`J™WJ™*J˜#J˜%J˜#J˜ J˜BJ˜CJ˜Bšœœ˜šœœœ˜HJ™/J˜5Jšœœ˜0J˜6Jšœœ˜0J˜5Jšœœ˜0J˜—šœœ˜0J™MJ˜J˜6Jšœœ˜0J˜5Jšœœ˜0J˜—šœ˜ J˜Jšœœ˜6Jšœœ˜6J˜9J˜——J˜——šŸ™Jšœœ˜!š œœœœœ˜SJ˜—š   œœœ œœ˜@Lšœ œœœ˜šœœœ˜+L˜.Lšœ œœœ˜Lšœœ˜Lšœœ œ˜FL˜Lšœ ˜Lšœ˜—Lšœœ˜%L˜L˜—š  œœœ˜2šœœœ˜+Jšœœœœ˜+J˜ Jšœ˜Lšœ˜—L˜L˜—š œœœœ ˜2Jšœœœœ˜Jšœœœ˜7Jšœœœ˜9Jšœœœ˜7J˜J˜—š œœ*œœ˜Ršœ˜J˜Y—J˜J˜—š œœ˜J˜ J˜ J˜Jšœœ˜Jšœœ˜Jšœ œ˜Jšœ˜J˜š œœœ˜5J˜,J˜J˜J˜—Jšœ'œœœ˜9š œœœœœœ˜HJ˜'J˜?šœœ ˜šœ˜J˜I—JšœE˜I—J˜AJšœ˜—š œœœœœœ˜FJ˜$J˜<šœœ ˜šœ˜J˜R—JšœC˜G—J˜AJšœ˜—š œœœœœœ˜FJ˜"J˜M˜'J˜G—J˜@Jšœ˜—J˜J˜—š œœœ œ ˜EJ™Jšœœ ˜š œ œœœœœ˜6Jšœœ*˜MJšœ˜—J˜J˜—š œœœ œ ˜LJšœœ ˜š œ œœœœœ˜6J˜Jšœœœ#˜TJšœ˜—J˜J˜—š œœœ œ ˜LJšœœ ˜š œ œœœœœ˜6J˜Jšœœœ#˜TJšœ˜—J˜J˜—š  œœ˜J˜ J˜ J˜Jšœœ˜Jšœœ˜Jšœ œ˜Jšœ˜J˜J˜]šœ œœ˜š  œœœ œœ ˜:J˜Jš œœœœ œ ˜Ošœ œ˜Jšœœ4˜>Jšœ˜J˜—J˜—š  œœœ˜.Jšœœ˜"J˜J˜šœ˜Jšœœ ˜šœ˜J˜3šœœœ˜"šœ œœ˜;Jšœ'˜+—Jšœ˜—J˜——J˜—š  œœœ˜.šœ œ˜Jš œœœœœ˜