Skip to content

Commit

Permalink
Merge pull request #596 from Inao0/master
Browse files Browse the repository at this point in the history
Add Venn Diagram for two sets
  • Loading branch information
akevalion authored Sep 7, 2023
2 parents 563a2d4 + 0994565 commit 16e2dc3
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
133 changes: 133 additions & 0 deletions src/Roassal3-Builders/RSCircleVennDiagram.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
"
This class creates a Venn Diagram to visualise two sets of data and their intersection.
This does not work for more than two sets for now.
The formula used to compute it are available at: https://dspace.library.uvic.ca/bitstream/handle/1828/128/phdGradStudiesMay24.pdf
"
Class {
#name : #RSCircleVennDiagram,
#superclass : #RSBuilder,
#instVars : [
'bigSet',
'smallSet',
'omega',
'treshold'
],
#category : #'Roassal3-Builders-VennDiagram'
}

{ #category : #examples }
RSCircleVennDiagram class >> example1 [

^ self new
bigSet: { 1. 2. 3. 4. 5. 6. 8. 9. 0. 0. 8 };
smallSet: { 1. 2. 10. 20. 50. 14 };
open
]

{ #category : #accessing }
RSCircleVennDiagram >> bigSet [

^ bigSet
]

{ #category : #accessing }
RSCircleVennDiagram >> bigSet: anObject [

bigSet := anObject asSet.
]

{ #category : #computation }
RSCircleVennDiagram >> computeDistance [

| bigRadius smallRadius intersection intersectionWeight lowBoundary highBoundary deltaFunction middle |
bigRadius := self computeRadius: bigSet.
smallRadius := self computeRadius: smallSet.
intersection := bigSet intersection: smallSet.
intersectionWeight := self weight: intersection.

lowBoundary := bigRadius - smallRadius.
highBoundary := bigRadius + smallRadius.
deltaFunction := [ :d |
| alpha beta delta |
alpha := 2
*
(d squared + bigRadius squared
- smallRadius squared / 2 * bigRadius * d)
arcCos.
beta := 2
*
(d squared - bigRadius squared
+ smallRadius squared / 2 * smallRadius
* d) arcCos.
delta := 0.5 * bigRadius squared
* (alpha - alpha) sin
+
(0.5 * smallRadius squared
* (beta - beta sin)).
delta ].

"Bisection algorithm"
middle := lowBoundary + highBoundary / 2.
[ (deltaFunction value: middle) - intersectionWeight < treshold ]
whileFalse: [
(deltaFunction value: middle) > intersectionWeight
ifTrue: [ lowBoundary := middle ]
ifFalse: [ highBoundary := middle ].
middle := lowBoundary + highBoundary / 2 ].
^ middle
]

{ #category : #accessing }
RSCircleVennDiagram >> computeRadius: aSet [

^ ((self weight: aSet) / Float pi) sqrt
]

{ #category : #initialization }
RSCircleVennDiagram >> initialize [
super initialize.
bigSet := Set new.
smallSet := Set new.
treshold := 0.001. "Accuracy of intersection area"
]

{ #category : #rendering }
RSCircleVennDiagram >> renderIn: aCanvas [

| bigRadius smallRadius distance |
(bigSet isEmpty or: [ smallSet isEmpty ]) ifTrue: [ ^ self ].

omega := bigSet asSet.
omega addAll: smallSet.
bigRadius := self computeRadius: bigSet.
smallRadius := self computeRadius: smallSet.
distance := self computeDistance.

aCanvas newCircle
radius: bigRadius * 10;
color: Color blue translucent;
position: 0 asPoint.
aCanvas newCircle
radius: smallRadius * 10;
position: distance * 10 @ 0;
color: Color red translucent.
aCanvas @ RSCanvasController.
]

{ #category : #accessing }
RSCircleVennDiagram >> smallSet [

^ smallSet
]

{ #category : #accessing }
RSCircleVennDiagram >> smallSet: anObject [

smallSet := anObject asSet.
]

{ #category : #accessing }
RSCircleVennDiagram >> weight: aSet [

^ aSet size / omega size
]
58 changes: 58 additions & 0 deletions src/Roassal3-Global-Tests/RSCircleVennDiagramTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Class {
#name : #RSCircleVennDiagramTest,
#superclass : #RSTest,
#instVars : [
'vennDiagram'
],
#category : #'Roassal3-Global-Tests-Builder'
}

{ #category : #running }
RSCircleVennDiagramTest >> setUp [
super setUp.

vennDiagram := RSCircleVennDiagram new.
]

{ #category : #tests }
RSCircleVennDiagramTest >> testBasicVennDiagramOpen [

| window |
window := vennDiagram open.
window delete
]

{ #category : #tests }
RSCircleVennDiagramTest >> testVennDiagramConvertsBigSetInputToSet [

vennDiagram bigSet: { 1 . 2 }.
self assert: vennDiagram bigSet class equals: Set.

]

{ #category : #tests }
RSCircleVennDiagramTest >> testVennDiagramConvertsSmallSetInputToSet [

vennDiagram smallSet: { 1 . 2 }.
self assert: vennDiagram smallSet class equals: Set.

]

{ #category : #tests }
RSCircleVennDiagramTest >> testVennDiagramOneSet [

vennDiagram bigSet: { 3 . 2 }.
vennDiagram build.
self assert: vennDiagram canvas shapes size equals: 0.

]

{ #category : #tests }
RSCircleVennDiagramTest >> testVennDiagramTwoSets [

vennDiagram bigSet: { 3 . 2 }.
vennDiagram smallSet: { 1. 3 . 2 }.
vennDiagram build.
self assert: vennDiagram canvas shapes size equals: 2.

]

0 comments on commit 16e2dc3

Please sign in to comment.