From VisualWorks®, 7.2 of October 20, 2003 on October 20, 2003 at 12:40:29 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>Vector</name> <environment>Examples</environment> <super>Core.UninterpretedBytes</super> <private>false</private> bytes <imports></imports> <category>Numeric-Vectors</category> <attributes> <package>DLLCC Vector Math Example</package> </attributes> </class> <comment> Examples.Vector
Instances of Vector are n-element vectors of floating-point numbers, each stored as 4 bytes in the vecotrs sequence of bytes. By convention x is floatAt: 1, y floatAt: 5, z floatAt: 9, and an extra value (for example, alpha) floatAt: 13. Instance Variables: *Indexed* Class Variables: VectorLibrary <VectorMath | FastVectorMath> object that provides the implementation of the math operations
</comment> <class> <name>VectorMathInternal</name> <environment>Examples</environment> <super>Core.Object</super> <private>false</private> none <imports></imports> <category>Numeric-Vectors</category> <attributes> <package>DLLCC Vector Math Example</package> </attributes> </class> <class> <name>VectorMathExternal</name> <environment>Examples</environment> <super>External.ExternalInterface</super> <private>false</private> none <imports> private Examples.VectorMathExternalDictionary.* </imports> <category>Numeric-Vectors</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>vector.dll</item> <item>vector.sl</item> <item>vector.so</item></libraryFiles> <libraryDirectories></libraryDirectories> <beVirtual>false</beVirtual> <optimizationLevel>full</optimizationLevel> <package>DLLCC Vector Math Example</package> </attributes> </class> <name>VectorLibrary</name> <environment>Examples.Vector</environment> <private>false</private> <constant>false</constant> <category>Defaults</category> <attributes> <package>DLLCC Vector Math Example</package> </attributes> <methods> Examples.Vector <category>accessing</category>
a ^self floatAt: 13
a: aNumber self floatAt: 13 put: aNumber asFloat
at: anIndex ^self slotAt: ((anIndex - 1) * 4) +1
at: anIndex put: aNumber self slotAt: ((anIndex - 1) * 4) +1 put: aNumber asFloat
h ^self floatAt: 13
h: aNumber self floatAt: 13 put: aNumber asFloat
isZeroVector 1 to: self sizeInBytes by: 4 do: [:i | (self slotAt: i) = 0 ifFalse: [^false]]. ^true
size ^self sizeInBytes // 4
w ^self floatAt: 13
w: aNumber self floatAt: 13 put: aNumber asFloat
x ^self floatAt: 1
x: aNumber self floatAt: 1 put: aNumber asFloat
x: ax y: ay z: az self floatAt: 1 put: ax . self floatAt: 5 put: ay. self floatAt: 9 put: az
x: ax y: ay z: az a: a self floatAt: 1 put: ax . self floatAt: 5 put: ay. self floatAt: 9 put: az. self floatAt: 13 put: a
x: ax y: ay z: az w: aw self floatAt: 1 put: ax . self floatAt: 5 put: ay. self floatAt: 9 put: az. self floatAt: 13 put: aw
y ^self floatAt: 5
y: aNumber self floatAt: 5 put: aNumber asFloat
z ^self floatAt: 9
z: aNumber self floatAt: 9 put: aNumber asFloat
</methods> <methods> Examples.Vector <category>arithmetic</category>
* aNumber ^VectorLibrary vector: self multiplyByScalar: aNumber result: self shallowCopy
+ aVector ^VectorLibrary vectorAdd: self and: aVector result: self shallowCopy
- aVector ^VectorLibrary vectorSubtract: self and: aVector result: self shallowCopy
/ aNumber ^VectorLibrary vector: self divideByScalar: aNumber result: self shallowCopy
</methods> <methods> Examples.Vector <category>functions</category>
angleBetween: v ^((self dotProduct: v) / (self magnitude * v magnitude)) arcCos radiansToDegrees
crossProduct: aVector ^VectorLibrary vectorCrossProduct: self with: aVector result: self shallowCopy
crossProductNormal: aVector ^VectorLibrary vectorCrossProduct: self with: aVector resultNormalized: self shallowCopy
distanceFrom: aVector ^(self - aVector) magnitude
dotProduct: aVector ^VectorLibrary vectorDotProduct: self and: aVector
magnitude ^VectorLibrary vectorMagnitude: self
negated ^VectorLibrary vectorNegate: self result: self shallowCopy
normal ^VectorLibrary vectorNormal: self result: self shallowCopy
rounded ^VectorLibrary vectorRound: self result: self shallowCopy
</methods> <methods> Examples.Vector <category>dispatching</category>
productFromDouble: num ^self * num
productFromFixedPoint: num ^self * num
productFromFloat: num ^self * num
productFromFraction: num ^self * num
productFromInfinitesimal: num ^self * num
productFromInfinity: num ^self * num
productFromInteger: num ^self * num
quotientFromDouble: num ^self / num
quotientFromFixedPoint: num ^self / num
quotientFromFloat: num ^self / num
quotientFromFraction: num ^self / num
quotientFromInfinitesimal: num ^self / num
quotientFromInfinity: num ^self / num
quotientFromInteger: num ^self / num
</methods> <methods> Examples.Vector <category>printing</category>
printOn: aStream aStream nextPut: $(. (1 to: self sizeInBytes by: self elementSize) do: [:i | (self slotAt: i) printOn: aStream] separatedBy: [ aStream nextPut: $,; space]. aStream nextPut: $).
</methods> <methods> Examples.Vector <category>converting</category>
, aNumber | bs new | bs := self sizeInBytes. new := self class new: self size+1. new replaceBytesFrom: 1 to: bs with: self startingAt: 1. new slotAt: bs+1 put: (self convert: aNumber). ^new
asPoint ^self x @ self y
</methods> <methods> Examples.Vector <category>private</category>
convert: aNumber ^aNumber asFloat
elementSize ^4
slotAt: byteIndex "Answer a single-precision (32 bit) floating point quantity starting at the given byteIndex." <primitive: 548> byteIndex isInteger ifTrue: [^(byteIndex < 1 or: [byteIndex + Float zero basicSize - 1 > self sizeInBytes]) ifTrue: [self subscriptBoundsError: byteIndex] ifFalse: [Float domainErrorSignal raiseRequestWith: byteIndex errorString: 'Invalid float at this index']]. ^byteIndex respondsToArithmetic ifTrue: [self slotAt: byteIndex asSmallInteger] ifFalse: [self nonIntegerIndexError: byteIndex]
slotAt: byteIndex put: aFloat "Store a single-precision (32 bit) floating point quantity starting at the given byteIndex." <primitive: 549> "The only way we can do this is by storing the Float byte-by-byte." | float | float := aFloat asFloat. self byteAt: byteIndex put: (float basicAt: 1). self byteAt: byteIndex + 1 put: (float basicAt: 2). self byteAt: byteIndex + 2 put: (float basicAt: 3). self byteAt: byteIndex + 3 put: (float basicAt: 4). ^float
</methods> <methods> Examples.Vector class <category>class initialization</category>
vectorLibrary: aVectorMath VectorLibrary := aVectorMath
</methods> <methods> Examples.Vector class <category>instance creation</category>
new: aSize ^self basicNew: aSize*4
r3BasisX ^self x: 1 y: 0 z: 0
r3BasisY ^self x: 0.0 y: 1.0 z: 0.0
r3BasisZ ^self x: 0 y: 0 z: 1
r3Zero ^self zeroRN: 3
red: xNum green: yNum blue: zNum alpha: wNum ^(self new: 4) x: xNum y: yNum z: zNum w: wNum
x: aNumber ^(self new: 1) x: aNumber
x: xNum y: yNum ^(self new: 2) x: xNum; y: yNum
x: xNum y: yNum z: zNum ^(self new: 3) x: xNum y: yNum z: zNum
x: xNum y: yNum z: zNum a: wNum ^(self new: 4) x: xNum y: yNum z: zNum a: wNum
x: xNum y: yNum z: zNum w: wNum ^(self new: 4) x: xNum y: yNum z: zNum w: wNum
zeroRN: size ^self new: size
</methods> <methods> Examples.Vector class <category>examples</category>
example1 "self example1" ^self r3BasisX + self r3BasisY + self r3BasisZ * 2.0
example2 "self example2" ^self r3BasisX - self r3BasisY + self r3BasisZ / 2.0
example3 "self example3" ^(1, 1, 1) dotProduct: (1, -2, 3)
example4 "self example4" ^(1, -1, 1) magnitude
example5 "self example5" "self example5 magnitude" ^(1, 1, 1) normal
example6 "self example6" ^(1, 1, 1) negated
example7 "self example7" ^(1, 2, 3) crossProduct: (1, 1, 1)
example8 "self example8" ^(3, 0, 0) crossProductNormal: (0, 3, 0)
example9 "self example9" ^((1, -1, 1) normal * 3) rounded
</methods> <methods> Examples.Vector class <category>testing</category>
test1 "Copmpare the Smalltalk code against the external code." "Vector test1" | tests internalResults externalResults | tests := self class organization listAtCategoryNamed: #examples. internalResults := Dictionary new. VectorMathInternal initialize. tests do: [:sel| internalResults at: sel put: ([self perform: sel] on: Error do: [:ex| ex errorString])]. externalResults := Dictionary new. VectorMathExternal initialize. tests do: [:sel| externalResults at: sel put: ([self perform: sel] on: Error do: [:ex| ex errorString])]. ^Dictionary withAll: ((tests reject: [:sel| (internalResults at: sel) = (externalResults at: sel)]) collect: [:sel| sel -> (Array with: (internalResults at: sel) with: (externalResults at: sel))])
test2 "Compare performance" "self test2" | u v w n t1 t2 il el | u := 1 , 1 , 1. v := u copy. w := u copy. n := 100000. il := VectorMathInternal new. el := VectorMathExternal new. t1 := Time millisecondsToRun: [n / 5 timesRepeat: [il vectorAdd: u and: v result: w. il vectorAdd: u and: v result: w. il vectorAdd: u and: v result: w. il vectorAdd: u and: v result: w. il vectorAdd: u and: v result: w]]. t2 := Time millisecondsToRun: [n / 5 timesRepeat: [el vectorAdd: u and: v result: w. el vectorAdd: u and: v result: w. el vectorAdd: u and: v result: w. el vectorAdd: u and: v result: w. el vectorAdd: u and: v result: w]]. ^#internal -> t1 -> #external -> t2 -> (t2 - t1 / t2 * 100.0)
</methods> <methods> Examples.VectorMathInternal <category>vector api</category>
vector: v1 divideByScalar: aNumber result: result | n | n := aNumber asFloat. 1 to: v1 sizeInBytes by: 4 do: [:i | result slotAt: i put: (v1 slotAt: i) / n]. ^result
vector: v1 multiplyByScalar: aNumber result: result | n | n := aNumber asFloat. 1 to: v1 sizeInBytes by: 4 do: [:i | result slotAt: i put: (v1 slotAt: i)*n]. ^result
vectorAdd: v1 and: v2 result: result 1 to: v1 sizeInBytes by: 4 do: [:i | result slotAt: i put: (v1 slotAt: i)+(v2 slotAt: i)]. ^result
vectorCrossProduct: v1 with: v2 result: result result x: (v1 y*v2 z) - (v1 z*v2 y). result y: (v1 z*v2 x) - (v1 x*v2 z). result z: (v1 x*v2 y) - (v1 y*v2 x). ^result
vectorCrossProduct: v1 with: v2 resultNormalized: result self vectorCrossProduct: v1 with: v2 result: result. self vectorNormal: result result: result. ^result
vectorDotProduct: v1 and: v2 | sum | sum := 0.0. 1 to: v1 sizeInBytes by: 4 do: [:i | sum := sum + ((v1 slotAt: i)*(v2 slotAt: i))]. ^sum
vectorMagnitude: v | sum | sum := 0.0. 1 to: v sizeInBytes by: 4 do: [:i | | num | num := v slotAt: i. sum := sum + (num*num)]. ^sum sqrt
vectorNegate: v1 result: v2 1 to: v1 sizeInBytes by: 4 do: [:i | v2 slotAt: i put: (v1 slotAt: i) negated]. ^v2
vectorNormal: v1 result: result | mag | mag := 0.0. 1 to: v1 sizeInBytes by: 4 do: [:i | | num | num := v1 slotAt: i. mag := mag + (num*num)]. mag := mag sqrt. mag = 0.0 ifTrue: [1 to: v1 sizeInBytes by: 4 do: [:i | result slotAt: i put: 0.0]] ifFalse: [1 to: v1 sizeInBytes by: 4 do: [:i | result slotAt: i put: (v1 slotAt: i) / mag]]. ^result
vectorRound: v1 result: v2 1 to: v1 sizeInBytes by: 4 do: [:i | v2 slotAt: i put: (v1 slotAt: i) rounded]. ^v2
vectorSubtract: v1 and: v2 result: result 1 to: v1 sizeInBytes by: 4 do: [:i | result slotAt: i put: (v1 slotAt: i)-(v2 slotAt: i)]. ^result
</methods> <methods> Examples.VectorMathInternal class <category>class initialization</category>
initialize Vector vectorLibrary: self new
</methods> <methods> Examples.VectorMathInternal class <category>fileIn/Out</category>
prerequisitesForLoading ^super prerequisitesForLoading addLast: Vector; yourself
</methods> <methods> Examples.VectorMathExternal class <category>class initialization</category>
initialize Vector vectorLibrary: self new
</methods> <methods> Examples.VectorMathExternal class <category>fileIn/Out</category>
prerequisitesForLoading "Ensure Vector is defined. Also define VectorMathInternal so that VectorMathApi is the default api." ^super prerequisitesForLoading addLast: Vector; addLast: VectorMathInternal; yourself
</methods> <methods> Examples.VectorMathExternal class <category>private</category>
libraryFilesSearchSignals "Answer a SignalCollection used to handle exceptions raised when scanning for library files. The signals answered by this method will result in those signals being ignored by the library search machinery. Clients should not answer signals they wish to receive." ^ExternalLibraryHolder libraryNotFoundSignal
</methods> <methods> Core.Number <category>converting</category>
, aNumber ^aNumber appendWith: self
appendWith: aNumber ^Examples.Vector x: aNumber y: self
</methods> <methods> Examples.VectorMathExternal <category>vector api</category>
vector: v1 divideByScalar: s result: result <C: _oop vectorDivideByScalar(_oop v1, float s, _oop result)> ^self externalAccessFailedWith: _errorCode
vector: v1 multiplyByScalar: s result: result <C: _oop vectorMultiplyByScalar(_oop v1, float s, _oop result)> ^self externalAccessFailedWith: _errorCode
vectorAdd: v1 and: v2 result: result <C: _oop vectorAdd(_oop v1, _oop v2 , _oop result)> ^self externalAccessFailedWith: _errorCode
vectorCrossProduct: v1 with: v2 result: result <C: _oop vectorCrossProduct(_oop v1, _oop v2, _oop result)> ^self externalAccessFailedWith: _errorCode
vectorCrossProduct: v1 with: v2 resultNormalized: result <C: _oop vectorCrossProductNormal(_oop v1, _oop v2, _oop result)> ^self externalAccessFailedWith: _errorCode
vectorDotProduct: v1 and: v2 <C: float vectorDotProduct(_oop v1, _oop v2 )> ^self externalAccessFailedWith: _errorCode
vectorMagnitude: v1 <C: float vectorMagnitude(_oop v1)> ^self externalAccessFailedWith: _errorCode
vectorNegate: v1 result: v2 <C: _oop vectorNegate(_oop v1, _oop v2)> ^self externalAccessFailedWith: _errorCode
vectorNormal: v1 result: result <C: _oop vectorNormal(_oop v1, _oop result)> ^self externalAccessFailedWith: _errorCode
vectorRound: v1 result: v2 <C: _oop vectorRound(_oop v1, _oop v2)> ^self externalAccessFailedWith: _errorCode
vectorSubtract: v1 and: v2 result: result <C: _oop vectorMinus(_oop v1, _oop v2 , _oop result)> ^self externalAccessFailedWith: _errorCode
</methods> <initialize> Examples.VectorMathInternal </initialize> <initialize> Examples.VectorMathExternal </initialize> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Object</name> <environment>Core</environment> <super></super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>Number</name> <environment>Core</environment> <super>Core.ArithmeticValue</super> <private>false</private> none <imports></imports> <category>Magnitude-Numbers</category> <attributes> <package>Magnitude-Numbers</package> </attributes> </class> <class> <name>UninterpretedBytes</name> <environment>Core</environment> <super>Core.Object</super> <private>false</private> bytes <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>ExternalInterface</name> <environment>External</environment> <super>Core.Object</super> <private>false</private> none includeFiles includeDirectories libraryFiles libraryDirectories virtual optimizationLevel <imports> private Kernel.OpcodePool.* </imports> <category>External-Interface</category> <attributes> <package>External-Interface</package> </attributes> </class>