Files
Class and Methods.R e Class and Methods extension.R e Class and Methods extension.R contengono le definizioni delle classi e dei metodi presentati in seguito. (VANNO MESSE IN ORDINE E BISOGNA RIDURRE A UN UNICO FILE)
Shapes_list.R contiene le forme sviluppate di default.
Rules_27102022.R contiene le regole per la creazone delle matrici.
Classe campo
La classe field contiene le informazioni neccessarie per
plottare il contenuto di una cella della matrice.
Vedi codice
field <- list(
shape = NULL,
size.x = list(),
size.y = list(),
rotation = list(),
pos.x = list(),
pos.y = list(),
lty =list(),
lwd = list(),
num = list(),
nv = list(),
shade =list(),
visible = NULL,
tag = list()
)shapeè un vettore contente stringhe di caratteri, ogni elemento della stringa indica la forma che si vuole sviluppare, per esempioc('circle','square')size.xesize.yun vettore o un scalare che danno informazione per il semi-asse maggiore e minore del elisse entro il quale è inscritto il poligono (corrispondono aradius.xeradius.ydel pacchettoDescTools)
library(DescTools)
Canvas(c(-5,5),c(-5,5)) # non è necessario il secondo c(-5,5) basta Canvas(c(-5,5))
DrawRegPolygon(x = 0, y = 0, radius.x=9,radius.y = 5, nv = 100)
DrawRegPolygon(x = 0, y = 0, radius.x=9,radius.y = 5, nv = 3)rotationangolo di rotazione in radianti (corrisponde arotdel pacchettoDescTools)xeyun vettore delle coordinate xy del centro del polygono (corrispondono axeydel pacchettoDescTools)ltyelwdrispettivamente il tipo di linea per il perimetro e lo spessore della stessa. Le figure di default hannolty=1elwd=2(corrispondono altyelwddel pacchettoDescTools)numil numero di volte che un oggetto è ripetuto sulla cella (più un desiderata che altro al momento)nvil numero di vertici del poligono (per cerchi/elipsinv = 100)shadeè il riempimento monocromatico di una formavisibleun vettore binario che contiene un 1 se la forma nella posizione relativa deve venire disegnata, uno 0 se non deve venire disegnata. Per esempiolist(shapes=c('circle','square'), visible = c(0,1))plottera solo il quadrato e non il cerchio.
Classe matrice
La classe Raven_matrix contiene tutte le informazioni
neccessarie per classificare la creazione della matrice.
Vedi codice
Raven<-list(
Sq1 = list(),
Sq2 = list(),
Sq3 = list(),
Sq4 = list(),
Sq5 = list(),
Sq6 = list(),
Sq7 = list(),
Sq8 = list(),
Sq9 = list(),
hrule = list(),
vrule = list()
)I campi da Sq1 a Sq9 corrispondono alle
celle della matrice.
## [,1] [,2] [,3]
## [1,] "Sq1" "Sq2" "Sq3"
## [2,] "Sq4" "Sq5" "Sq6"
## [3,] "Sq7" "Sq8" "Sq9"
Ogni cella della matrice andrà a contenere un oggetto di classe
field contenente tutte le possibili forme al suo
interno.
I campi hrule e vrule sono due vettori
contententi le regole.
hrulecontiene le regole che verranno applicate secondo la logica orizzontale. L’ordine delle regole nel vettore corrisponde al ordine di applicazione.vrulecontiene le regole che verranno applicate secondo la logica verticale. L’ordine delle regole nel vettore corrisponde al ordine di applicazione.
Logiche più complesse vengono ottenute tramite composizioni di orizzontale e verticale.
Nella seuente tabella è presente una lista delle forme al momento
implementate nel pacchetto. Nella colonna name è presente
il nome della forma, nella colonna num_shapes il numero di
forme di cui è composta la figura. Il resto delle colonne (i.e.,
small, fill , rotate) i tag che
specificano diverse caratteristiche della figura, nello specifico se la
figura può essere rimpicciolita, se può essere usata come riempimento e
se può essere ruotata.
Vedi tabella delle forme
| name | num_shapes | small | fill | rotate |
|---|---|---|---|---|
| bow.tie | 2 | FALSE | TRUE | TRUE |
| circle | 1 | TRUE | FALSE | FALSE |
| cross | 1 | FALSE | TRUE | FALSE |
| cross.dice | 1 | FALSE | FALSE | FALSE |
| diagline | 1 | FALSE | TRUE | FALSE |
| diagline.inv | 1 | FALSE | TRUE | FALSE |
| dice | 1 | FALSE | FALSE | FALSE |
| dot | 0 | FALSE | TRUE | FALSE |
| e.hexagon | 1 | TRUE | FALSE | TRUE |
| ellipse | 1 | TRUE | FALSE | FALSE |
| h.arc.left.down | 1 | TRUE | FALSE | FALSE |
| h.arc.left.up | 1 | TRUE | FALSE | FALSE |
| h.arc.right.down | 1 | TRUE | FALSE | FALSE |
| h.arc.right.up | 1 | TRUE | FALSE | FALSE |
| hexagon | 1 | TRUE | TRUE | FALSE |
| hline | 1 | FALSE | TRUE | FALSE |
| horizontal.eight | 2 | FALSE | FALSE | FALSE |
| horizontal_eight | 1 | FALSE | TRUE | FALSE |
| lily | 4 | FALSE | FALSE | FALSE |
| pentagon | 1 | TRUE | FALSE | FALSE |
| pie.2 | 2 | FALSE | TRUE | FALSE |
| pie.2.inv | 2 | FALSE | TRUE | FALSE |
| pie.4 | 4 | FALSE | TRUE | FALSE |
| rot.hexagon | 1 | TRUE | FALSE | FALSE |
| s.horizontal | 2 | FALSE | TRUE | FALSE |
| s.horizontal.inv | 2 | FALSE | TRUE | FALSE |
| s.lily | 1 | FALSE | TRUE | FALSE |
| s.vertical | 2 | FALSE | TRUE | FALSE |
| s.vertical.inv | 2 | FALSE | TRUE | FALSE |
| s_horizontal | 1 | FALSE | TRUE | FALSE |
| s_horizontal.inv | 1 | FALSE | TRUE | FALSE |
| s_vertical | 1 | FALSE | TRUE | FALSE |
| s_vertical.inv | 1 | FALSE | TRUE | FALSE |
| semi.circle | 1 | FALSE | TRUE | TRUE |
| semi.circle.inv | 1 | FALSE | TRUE | TRUE |
| semi.circle.inv1 | 1 | FALSE | TRUE | TRUE |
| semi.circle1 | 1 | FALSE | TRUE | TRUE |
| slice | 1 | FALSE | TRUE | TRUE |
| square | 1 | TRUE | FALSE | FALSE |
| square4 | 4 | FALSE | FALSE | FALSE |
| star | 2 | TRUE | TRUE | FALSE |
| triangle | 1 | TRUE | FALSE | FALSE |
| u.bow.tie | 1 | FALSE | TRUE | TRUE |
| u.pie.2 | 1 | FALSE | TRUE | FALSE |
| u.pie.2.inv | 1 | FALSE | TRUE | FALSE |
| u.pie.4 | 1 | FALSE | TRUE | FALSE |
| u.star | 1 | TRUE | TRUE | FALSE |
| v.arc.left.down | 1 | TRUE | FALSE | FALSE |
| v.arc.left.up | 1 | TRUE | FALSE | FALSE |
| v.arc.right.down | 1 | TRUE | FALSE | FALSE |
| v.arc.right.up | 1 | TRUE | FALSE | FALSE |
| vertical.eight | 2 | FALSE | FALSE | FALSE |
| vertical_eight | 1 | FALSE | TRUE | FALSE |
| vline | 1 | FALSE | TRUE | FALSE |
| X | 1 | FALSE | TRUE | FALSE |
Forme di Default
Forme Geometriche
Segmenti
Archi
Forme puntinate
Concatenazione di Forme
La funzione cof concatena diversi campi esattamente
secondo la stessa logica di c()
Mostra codice
source("Class and Methods.R")
cof(square(),circle(),pentagon())## $shape
## [1] "square" "circle" "pentagon"
##
## $size.x
## $size.x[[1]]
## [1] 15
##
## $size.x[[2]]
## [1] 10
##
## $size.x[[3]]
## [1] 15
##
##
## $size.y
## $size.y[[1]]
## [1] 15
##
## $size.y[[2]]
## [1] 10
##
## $size.y[[3]]
## [1] 15
##
##
## $theta.1
## $theta.1[[1]]
## [1] 0
##
## $theta.1[[2]]
## [1] 0
##
## $theta.1[[3]]
## [1] 0
##
##
## $theta.2
## $theta.2[[1]]
## [1] 0
##
## $theta.2[[2]]
## [1] 0
##
## $theta.2[[3]]
## [1] 0
##
##
## $rotation
## $rotation[[1]]
## [1] 0.7853982
##
## $rotation[[2]]
## [1] 0
##
## $rotation[[3]]
## [1] 1.570796
##
##
## $pos.x
## $pos.x[[1]]
## [1] 0
##
## $pos.x[[2]]
## [1] 0
##
## $pos.x[[3]]
## [1] 0
##
##
## $pos.y
## $pos.y[[1]]
## [1] 0
##
## $pos.y[[2]]
## [1] 0
##
## $pos.y[[3]]
## [1] 0
##
##
## $lty
## $lty[[1]]
## [1] 1
##
## $lty[[2]]
## [1] 1
##
## $lty[[3]]
## [1] 1
##
##
## $lwd
## $lwd[[1]]
## [1] 3
##
## $lwd[[2]]
## [1] 2
##
## $lwd[[3]]
## [1] 3
##
##
## $num
## $num[[1]]
## [1] 1
##
## $num[[2]]
## [1] 1
##
## $num[[3]]
## [1] 1
##
##
## $nv
## $nv[[1]]
## [1] 4
##
## $nv[[2]]
## [1] 100
##
## $nv[[3]]
## [1] 5
##
##
## $shade
## $shade[[1]]
## [1] NA
##
## $shade[[2]]
## [1] NA
##
## $shade[[3]]
## [1] NA
##
##
## $visible
## [1] 1 1 1
##
## $tag
## $tag[[1]]
## [1] "simple" "small"
##
## $tag[[2]]
## [1] "simple" "small"
##
## $tag[[3]]
## [1] "simple" "small"
##
##
## attr(,"class")
## [1] "field"
Creazione di una matrice
La funzione Raven crea una matrice di Raven in cui tutte
le celle della matrice vengono inizializzate identiche alla cella
Sq1, e vengono inizializzate le regole.
St1classe field che contiene i campi di partenza per tutte le cellehrulevettore delle regole applicabili con logica orizzontalevrulevettore delle regole applicabili con logica verticale
M<-Raven(st1=square(),hrule=c("size"),vrule=c("identity"))
draw(M)Nella matrice M le regole non sono ancora state
applicate, infatti nel plot d’esempio i quadrati hanno tutti le stesse
dimensioni.
L’estensione del metodo apply applica le regole presenti
nella matrice a tutte le celle. Al momento applica le regole prima in
riga e poi in colonna.
M<-apply(M)
draw(M)Regole (Field)
Rotazione
Il metodo rotazione cambia il valore field$rotation di
rotazioni fisse con un angolo di \(\frac{\pi}{4}\)
objil contenuto di una cella della matricenrappresenta l’ennesimo elemento a cui viene applicata la regola. Per esempio se la regola viene applicata orizzontalmenten =1perSq1,Sq4eSq7,n =2perSq2,Sq5eSq8e per finiren =3perSq3,Sq6eSq9.
Vedi codice
rotation.field<-function(obj,n,...) {
obj$rotation[[1]]<-obj$rotation[[1]]+(n-1)*pi/4
return(obj)
}La rotazione può essere applicata con le regole orizzontali, verticali e diagonalmente da basso a sinistra a alto-destra (TL-LR) applicando prima in orizzontale poi verticale.
#Horizontal
M<-apply(Raven(st1=pentagon(),hrule=c("rotation"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=pentagon(),hrule=c("identity"),vrule=c("rotation")))
draw(M)# Top Left Low Right
M<-apply(Raven(st1=pentagon(),hrule=c("rotation"),vrule=c("rotation")))
draw(M)Dimensione
Il metodo di cambio di dimensioni, riduce i valori di
field$size.x e field$size.y di un valore
costante pari a numero di riga (o colonna) della matrice per \(k=.9\). Se per esempio la regola è
applicata orizzontalmente, gli elementi nelle celle
Sq1,Sq4,sq7della prima colonna hanno dimensioni \((\frac{x}{k},\frac{y}{k})\), gli elementi
nelle celle Sq2,Sq5,sq8 hanno dimensioni \((\frac{x}{2k},\frac{y}{2k})\) e quelli
nella terza colonna \((\frac{x}{3k},\frac{y}{3k})\).
Vedi codice
size.field<-function(obj,n,...) {
obj$size.x[[1]]<-obj$size.x[[1]]/(n*.9)
obj$size.y[[1]]<-obj$size.y[[1]]/(n*.9)
return(obj)
}La cambio di dimensione può essere applicata con le regole orizzontali, verticali e diagonalmente da basso a sinistra a alto-destra (TL-LR) applicando prima in orizzontale poi verticale.
#Horizontal
M<-apply(Raven(st1=circle(),hrule=c("size"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=circle(),hrule=c("identity"),vrule=c("size")))
draw(M)# Top Left Low Right
M<-apply(Raven(st1=circle(),hrule=c("size"),vrule=c("size")))
draw(M)Cambio delle forme
Il metodo di cambio di forma manipola il campo
field$visible in modo di alternare tre diverse forme.
L’ordine di applicazione va dalla terza alla prima forma. Per ogni cella
individua quali forme sono visibili - Se più di una forma è visibile le
rende tutte invisibili e seleziona solo quella in posizione \(n\). Dove \(n\) è l’indice di riga (o di colonna) - Se
una sola forma è visibile la regola la mette invisibile e seleziona
quella a distante \(n\) nel vettore
index
Vedi codice
diff_shapes.field<-function(obj,n,...) {
if(length(obj$visible)!=3)
{
stop("You must have at least three forms to change shapes!")
}
#index<-c(3:1,3:1,3:1) TL-LR
index<-c(1:3,1:3,1:3) #TR-LL
pos<-which(obj$visible==1)
if(length(pos)>1){
obj$visible[pos]<-0
obj$visible[index[n]]<-1
}else {
obj$visible[pos]<-0
obj$visible[index[pos+n]]<-1
}
return(obj)
}Il cambio di forma può essere applicato con le regole orizzontali, verticali e diagonalmente da basso a sinistra a alto-destra (TL-LR) applicando prima in orizzontale poi verticale.
#Horizontal
M<-apply(Raven(st1=cof(circle(),square(),pentagon()),hrule=c("diff_shapes"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=cof(circle(),square(),pentagon()),hrule=c("identity"),vrule=c("diff_shapes")))
draw(M)# Top Left Low Right
M<-apply(Raven(st1=cof(circle(),square(),pentagon()),hrule=c("diff_shapes"),vrule=c("diff_shapes")))
draw(M)Contorno
La regola per il cambiamento del contorno può cambiare sia lo
spessore che il tipo di contorno utilizzando i parametri standard di R
lwd e lty. Tre diversi spessori vengono
utilizzati dipendenti dal indice di riga (o di colonna) \(n\). Le forme di default hanno come
spessore di partenza \(2\). Il tipo di
contorno cambia allo stesso modo in funzione del indice di riga (o di
colonna) \(n\).
margin.field<-function(obj,n,rules,...){
index<-c(3:1,3:1,3:1)
if(grepl("lwd",rules)){
obj$lwd[[1]]<- index[obj$lwd[[1]]+n]+1
}else if(grepl("lty",rules)){
obj$lty[[1]]<-index[obj$lty[[1]]+n]
}
return(obj)
}Spessore del contorno
#Horizontal
M<-apply(Raven(st1=pentagon(),hrule=c("lwd"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=pentagon(),hrule=c("identity"),vrule=c("lwd")))
draw(M)# Top Left Low Right
M<-apply(Raven(st1=pentagon(),hrule=c("lwd"),vrule=c("lwd")))
draw(M)Tipo del contorno
#Horizontal
M<-apply(Raven(st1=pentagon(),hrule=c("lty"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=pentagon(),hrule=c("identity"),vrule=c("lty")))
draw(M)# Top Left Low Right
M<-apply(Raven(st1=pentagon(),hrule=c("lty"),vrule=c("lty")))
draw(M)Riempimento
Il riempimento monocromatico viene applicato campo per campo.
Riempimento monocromatico
La regola per il rimepimento monocromatico cambia il campo
field$shade tra i valori white,
black e grey. I tre diversi riempimenti
vengono assegnati tramite l’indice di riga (o di colonna) \(n\). Il solo perimentro si ottiene con
field$shade="none"
fill.field<-function(obj,n,...){
index <- rep(c("white","grey","black"),3)
pos <- index==obj$shade[[1]]
if(is.na(sum(pos)))
{
obj$shade[[1]]<-index[n]
}else{
pos <- which(pos)
obj$shade[[1]]<-index[pos+n]
}
return(obj)
}#Horizontal
M<-apply(Raven(st1=pentagon(),hrule=c("fill"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=pentagon(),hrule=c("identity"),vrule=c("fill")))
draw(M)# Top Left Low Right
M<-apply(Raven(st1=pentagon(),hrule=c("fill"),vrule=c("fill")))
draw(M)Multifill
Riempimento con le righe
M1<-apply(Raven(bow.tie(),
hrule= "multifill", vrule = "multifill"))
draw(M1)Riempimento con altre forme ?????
m1 = apply(Raven(st1 = cof(dot(),
s.lily(),
square(s.x = 5, s.y = 5,
shd = "black", rot = pi/2)),
hrule = "diff_shapes"))
m2 = apply(Raven(st1=pentagon(),
hrule=c("identity"),
vrule=c("identity")))
draw(com(m1, m2))Logica
Le regole logiche vengono applicate per riga e per colonna con 3 o più forme. Presento gli elementi basi per applicare la logica in termini insiemistici.
logic.field<-function(obj,n,rule,seed,...) {
if(length(obj$shape)<3)
{
stop("You must have three forms to apply a logical AND !")
}
##gestione di più immagini
domain<-1:length(obj$shape)
obj$visible[domain]<-1
set.seed(seed)
fixed<-sample(domain,round(length(obj$shape)/5))
domain<-setdiff(domain,fixed)
half<-length(domain)%/%2
index<-list()
index[[1]]<-sample(domain,half)
index[[2]]<-sample(setdiff(domain,index[[1]]),half)
if(rule=="AND"){
index[[3]]<-union(index[[1]],index[[2]])
obj$visible[index[[n]]]<-0
}else if(rule=="OR"){
if(n<3){
obj$visible[index[[n]]]<-0
}
}else if(rule=="XOR"){
index[[3]]<-union(setdiff(domain,union(index[[1]],index[[2]])),fixed)
obj$visible[index[[n]]]<-0
}
return(obj)
}domainè l’insieme delle forme \(D\)fixedè l’intersezione tra la prima e la seconda cella \(C_1 \cap C_2\)index[[1]]è l’insieme delle forme nella prima cella meno l’intersezione \(C_1 / \{ C_1 \cap C_2\}\)index[[2]]è l’insieme delle forme nella seconda cella meno l’intersezione \(C_2 / \{ C_1 \cap C_2\}\)
Questi insiemi vengono mantenuti costanti per riga (o per colonna) tramite dei differenti semi.
AND
#Horizontal
M<-apply(Raven(st1=cof(pentagon(),vertical.eight(),horizontal.eight()),hrule=c("AND"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=cof(pentagon(),vertical.eight(),horizontal.eight()),vrule=c("AND"),hrule=c("identity")))
draw(M)OR
#Horizontal
M<-apply(Raven(st1=cof(pentagon(),vertical.eight(),horizontal.eight()),hrule=c("OR"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=cof(pentagon(),vertical.eight(),horizontal.eight()),vrule=c("OR"),hrule=c("identity")))
draw(M)Xor
#Horizontal
M<-apply(Raven(st1=cof(pentagon(),vertical.eight(),horizontal.eight()),hrule=c("XOR"),vrule=c("identity")))
draw(M)#Vertical
M<-apply(Raven(st1=cof(pentagon(),vertical.eight(),horizontal.eight()),vrule=c("XOR"),hrule=c("identity")))
draw(M)