Object subclass: #EPFLGeometric instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'EPFL-Geometric'! EPFLGeometric comment: 'Geometrics are immutable, strictly mathematical entities that model geometric abstractions in the real plane, such as Lines and Circles. EPFLGeometric is an abstract class and subclasses are expected to implement the following methods: center returns the center of gravity of the geometric rotatedBy: rotates the geometric around its own center scaledBy: scales the geometric by a given factor (invariant: the center of gravity) translatedByX:andY: operates a translation along the two axis '! !EPFLGeometric methodsFor: 'accessing'! center "returns the center of the geometric object" ^self subclassResponsibility.! ! !EPFLGeometric methodsFor: 'transforming'! rotatedBy: angle "abstract - rotation around the center" ^self subclassResponsibility.! rotatedBy: angle around: aPoint "rotation around a given point" | center newCenter | self translatedBy: (aPoint negated). center := self center. newCenter := (center class new) r: (center r) theta: ((center theta) + angle). self translatedByX: ((newCenter x) - (center x)) andY: ((newCenter y) - (center y)). self translatedBy: aPoint. self rotatedBy: angle.! scaledBy: factor "abstract - scaling related to the center" ^self subclassResponsibility.! translatedBy: aPoint "translation" ^self translatedByX: (aPoint x) andY: (aPoint y).! translatedByX: xOffset andY: yOffset "abstract - translation along x and y." ^self subclassResponsibility.! ! !EPFLGeometric methodsFor: 'initialize-release'! initialize "Initialization of the instance" ^self.! ! EPFLGeometric subclass: #EPFLSegment instanceVariableNames: 'start end ' classVariableNames: '' poolDictionaries: '' category: 'EPFL-Geometric'! EPFLSegment comment: 'EPFLSegment models the geometric notion of a line segment in the real plane. This class might be more properly named ''EPFLOrientedSegment'' since it distinguishes between a start and end point (rather than just using two endpoints); these lines have a direction. Instance variables: start Coordinates of the line''s start. end Coordinates of the line''s end. '! !EPFLSegment methodsFor: 'transforming'! rotatedBy: angle "rotation around the center" | center | center := self center. start rotatedBy: angle around: center. end rotatedBy: angle around: center.! scaledBy: factor "scaling related to the center" | center | center := self center. self translatedBy: (center negated). start x: ((start x) * factor) y: ((start y) * factor). end x: ((end x) * factor) y: ((end y) * factor). self translatedBy: center! translatedByX: x andY: y "translation along the two axis" start translatedByX: x andY: y. end translatedByX: x andY: y.! ! !EPFLSegment methodsFor: 'initialize-release'! start: aPoint end: anotherPoint "..." start := aPoint. end := anotherPoint.! ! !EPFLSegment methodsFor: 'accessing'! center "the center of the segment" | center | center := EPFLPoint new. center x: (((start x) + (end x)) / 2) y: (((start y) + (end y)) / 2). ^center! end ^end! start ^start! ! !EPFLSegment methodsFor: 'printing'! printOn: aStream "prints a human-readable version of the object" aStream print: self class; nextPutAll: ' ('; print: start; space; print: end; nextPut: $).! ! EPFLGeometric subclass: #EPFLTriangle instanceVariableNames: 'a b c ' classVariableNames: '' poolDictionaries: '' category: 'EPFL-Geometric'! EPFLTriangle comment: 'EPFLTriangle models the geometric notion of a triangle in the real plane. Instance variables: a vertice of the triangle. b '''' '''' c '''' '''''! !EPFLTriangle methodsFor: 'accessing'! a ^a! b ^b! c ^c! center "center of triangle" | center | center := EPFLPoint new. center x: (((a x) + (b x) + (c x)) / 3) y: (((a y) + (b y) + (c y)) / 3). ^center! ! !EPFLTriangle methodsFor: 'initialize-release'! a: aPoint1 b: aPoint2 c: aPoint3 a := aPoint1. b := aPoint2. c := aPoint3! ! !EPFLTriangle methodsFor: 'printing'! printOn: aStream aStream print: self class; nextPutAll: ' ('; print: a; space; print: b; space; print: c; nextPut: $)! ! !EPFLTriangle methodsFor: 'transforming'! rotatedBy: angle "rotation around the center" | center | center := self center. a rotatedBy: angle around: center. b rotatedBy: angle around: center. c rotatedBy: angle around: center.! scaledBy: factor "scaling related to the center" | center | center := self center. self translatedBy: (center negated). a x: ((a x) * factor) y: ((a y) * factor). b x: ((b x) * factor) y: ((b y) * factor). c x: ((c x) * factor) y: ((c y) * factor). self translatedBy: center! translatedByX: x andY: y "translation along the two axis" a translatedByX: x andY: y. b translatedByX: x andY: y. c translatedByX: x andY: y.! ! EPFLGeometric subclass: #EPFLCircle instanceVariableNames: 'center radius ' classVariableNames: '' poolDictionaries: '' category: 'EPFL-Geometric'! EPFLCircle comment: 'Circle represents a circle in the real plane. This is implemented separately (rather than by use of a special case of elliptical arc) for conceptual simplicity. Instance variables: center Coordinates of the circle''s center. radius Radius of the circle.'! !EPFLCircle methodsFor: 'printing'! printOn: aStream aStream print: self class; nextPutAll: ' ('; print: center; space; print: radius; nextPut: $).! ! !EPFLCircle methodsFor: 'initialize-release'! center: aPoint radius: aNumber center := aPoint. radius := aNumber.! ! !EPFLCircle methodsFor: 'accessing'! center "the center of the circle" ^center.! ! !EPFLCircle methodsFor: 'transforming'! rotatedBy: angle "rotates the circle (in fact, does NOTHING ;-)" ^self.! scaledBy: factor "scales the circle, changes radius" radius := radius * factor. ^self.! translatedByX: xOffset andY: yOffset "translation along the two axis, by moving the center" center translatedByX: xOffset andY: yOffset. ^self.! ! EPFLGeometric subclass: #EPFLPoint instanceVariableNames: 'x y ' classVariableNames: '' poolDictionaries: '' category: 'EPFL-Geometric'! EPFLPoint comment: 'EPFLPoint represents an x-y pair of numbers, usually designating a location in the real plane. A point can sometimes play the role of a vector starting at the origin. Instance Variables: x usually x coordinate y usually y coordinate'! !EPFLPoint methodsFor: 'polar coordinates'! r ^ ((x squared) + (y squared)) sqrt.! theta "Answer the angle the receiver makes with origin in radians. right is 0; down is (Pi / 2) radians (90 degrees). Result will be between 0 and (2 * Pi) radians" | tan theta pi | ^(x = 0) ifTrue: ["Use the most accurate value for Pi appropriate to the type of Point" pi := (x+y) asLimitedPrecisionReal class pi. y >= 0 ifTrue: [pi * 0.5] ifFalse: [pi * 1.5]] ifFalse: [tan := y asLimitedPrecisionReal / x asLimitedPrecisionReal. theta := tan arcTan. x < 0 ifTrue: [theta + theta class pi] ifFalse: [theta < 0 ifTrue: [theta + (theta class pi * 2)] ifFalse: [theta]]]! ! !EPFLPoint methodsFor: 'initialize-release'! r: r theta: theta "initialisation of a point, using polar coordinates" ^self x: (r * (theta cos)) y: (r * (theta sin)).! x: aNumber y: anotherNumber x := aNumber. y := anotherNumber. ^self! ! !EPFLPoint methodsFor: 'arithmetic'! negated "returns a negated copy of the object" ^(self copy) x: (x negated) y: (y negated).! ! !EPFLPoint methodsFor: 'accessing'! center ^self copy.! x ^x! y ^y! ! !EPFLPoint methodsFor: 'printing'! printOn: aStream aStream print: self class. aStream nextPutAll: ' ('. aStream print: x rounded. aStream space. aStream print: y rounded. aStream nextPut: $).! ! !EPFLPoint methodsFor: 'transforming'! rotatedBy: angle "rotation around the center" ^self.! scaledBy: factor "scaling related to the center" ^self.! translatedByX: xOffset andY: yOffset "translation along the two axis" ^self x: (x+xOffset) y: (y+yOffset).! !