-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
db77222
commit c3071cf
Showing
15 changed files
with
773 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
This code and its output are licensed under the | ||
Creative Commons Attribution-NonCommercial-NoDerivatives | ||
4.0 International (CC BY-NC-ND 4.0) License. | ||
https://creativecommons.org/licenses/by-nc-nd/4.0/ | ||
*/ | ||
|
||
// Gradient Graphs | ||
// Edge Display Class | ||
// Author: Brittni Watkins | ||
|
||
class EdgeDisplay { | ||
constructor(aPositionPercentage, bPositionPercentage, aColor, bColor) { | ||
this.aPositionPercentage = aPositionPercentage.copy(); | ||
this.bPositionPercentage = bPositionPercentage.copy(); | ||
this.aColor = aColor; | ||
this.bColor = bColor; | ||
this.aColorWithAlpha = new Color(aColor.getColor()); | ||
this.aColorWithAlpha.setAlpha(100); | ||
this.bColorWithAlpha = new Color(bColor.getColor()); | ||
this.bColorWithAlpha.setAlpha(100); | ||
this.displayCircle = true; | ||
this.displayLine = true; | ||
} | ||
|
||
getCenterPercentage() { | ||
let xPercentage = (this.aPositionPercentage.x + this.bPositionPercentage.x) / 2; | ||
let yPercentage = (this.aPositionPercentage.y + this.bPositionPercentage.y) / 2; | ||
return createVector(xPercentage, yPercentage); | ||
} | ||
|
||
getDistance() { | ||
let distance = dist(this.aPositionPercentage.x * width, this.aPositionPercentage.y * height, this.bPositionPercentage.x * width, this.bPositionPercentage.y * height); | ||
return distance; | ||
} | ||
|
||
display() { | ||
if (this.displayLine) { | ||
this.displayGradientLine(); | ||
} | ||
|
||
if (this.displayCircle) { | ||
this.displayGradientCircle(); | ||
} | ||
} | ||
|
||
toggleDisplayLine() { | ||
this.displayLine = !this.displayLine; | ||
} | ||
|
||
toggleDisplayCircle() { | ||
this.displayCircle = !this.displayCircle; | ||
} | ||
|
||
displayGradientLine() { | ||
let numSegments = 10; | ||
let start = this.aPositionPercentage.copy(); | ||
let end; | ||
|
||
for (let i = 1; i <= numSegments; i++) { | ||
let colorPercentage = (i - 1) * (1.0 / numSegments); | ||
let percent = i * (1.0 / numSegments); | ||
end = p5.Vector.lerp(this.aPositionPercentage, this.bPositionPercentage, percent); | ||
stroke(lerpColor(this.aColor.getColor(), this.bColor.getColor(), colorPercentage)); | ||
line(start.x * width, start.y * height, end.x * width, end.y * height); | ||
start.set(end); | ||
} | ||
} | ||
|
||
displayGradientCircle() { | ||
let centerPercentage = this.getCenterPercentage(); | ||
let distance = this.getDistance(); | ||
let radius = distance / 2; | ||
let theta = 0; | ||
let numPoints = 50; | ||
beginShape(); | ||
noStroke(); | ||
|
||
for (let i = 0; i < numPoints; i++) { | ||
let baseX = centerPercentage.x * width; | ||
let baseY = centerPercentage.y * height; | ||
let x = baseX + (cos(theta) * radius); | ||
let y = baseY + (sin(theta) * radius); | ||
let d = dist(this.aPositionPercentage.x * width, this.aPositionPercentage.y * height, x, y); | ||
let col = lerpColor(this.aColorWithAlpha.getColor(), this.bColorWithAlpha.getColor(), d / distance); | ||
fill(col); | ||
vertex(x, y); | ||
theta += TWO_PI / numPoints; | ||
} | ||
|
||
endShape(CLOSE); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
This code and its output are licensed under the | ||
Creative Commons Attribution-NonCommercial-NoDerivatives | ||
4.0 International (CC BY-NC-ND 4.0) License. | ||
https://creativecommons.org/licenses/by-nc-nd/4.0/ | ||
*/ | ||
|
||
// Graident Graphs | ||
// Graph Display Class | ||
// Author: Brittni Watkins | ||
|
||
class GraphDisplay { | ||
constructor(graph, center, width, height, colorGenerators) { | ||
this.graph = graph; | ||
this.center = center.copy(); | ||
this.width = width; | ||
this.height = height; | ||
this.nodeDisplays = new Map(); | ||
this.edgeDisplays = []; | ||
this.colorGenerators = colorGenerators; | ||
this.buildNodeDisplays(); | ||
this.buildEdgeDisplays(); | ||
} | ||
|
||
buildNodeDisplays() { | ||
let nodes = this.graph.getNodes(); | ||
|
||
nodes.forEach(node => { | ||
let position = this.getScreenPositionPercentage(node); | ||
let colorGeneratorIndex = randomInt(0, this.colorGenerators.length); | ||
let colorGenerator = this.colorGenerators[colorGeneratorIndex]; | ||
let radius = min(width, height) / 100.0; | ||
let nodeDisplay = new NodeDisplay(position, radius, new Color(colorGenerator.getRandomColor())); | ||
this.nodeDisplays.set(node, nodeDisplay); | ||
}); | ||
} | ||
|
||
toggleDisplayLine() { | ||
this.edgeDisplays.forEach(edgeDisplay => { | ||
edgeDisplay.toggleDisplayLine(); | ||
}); | ||
} | ||
|
||
toggleDisplayCircle() { | ||
this.edgeDisplays.forEach(edgeDisplay => { | ||
edgeDisplay.toggleDisplayCircle(); | ||
}); | ||
} | ||
|
||
toggleDisplayNode() { | ||
this.nodeDisplays.forEach(nodeDisplay => { | ||
nodeDisplay.toggleDisplayNode(); | ||
}); | ||
} | ||
|
||
buildEdgeDisplays() { | ||
let edges = this.graph.getEdges(); | ||
|
||
edges.forEach(edge => { | ||
let a = edge.getA(); | ||
let b = edge.getB(); | ||
let aPositionPercentage = this.getScreenPositionPercentage(a); | ||
let bPositionPercentage = this.getScreenPositionPercentage(b); | ||
let aDisplay = this.nodeDisplays.get(a); | ||
let bDisplay = this.nodeDisplays.get(b); | ||
let aColor = aDisplay.getColor(); | ||
let bColor = bDisplay.getColor(); | ||
let edgeDisplay = new EdgeDisplay(aPositionPercentage, bPositionPercentage, aColor, bColor); | ||
this.edgeDisplays.push(edgeDisplay); | ||
}); | ||
} | ||
|
||
getScreenPositionPercentage(node) { | ||
let position = node.getPosition(); | ||
let scale = this.graph.getScale(); | ||
let graphMin = scale.getMin(); | ||
let graphMax = scale.getMax(); | ||
let minScreenXPercentage = (this.center.x - (this.width / 2.0)) / width; | ||
let maxScreenXPercentage = (this.center.x + (this.width / 2.0)) / width; | ||
let minScreenYPercentage = (this.center.y - (this.height / 2.0)) / height; | ||
let maxScreenYPercentage = (this.center.y + (this.height / 2.0)) / height; | ||
let x = map(position.x, graphMin.x, graphMax.x, minScreenXPercentage, maxScreenXPercentage); | ||
let y = map(position.y, graphMin.y, graphMax.y, minScreenYPercentage, maxScreenYPercentage); | ||
return createVector(x, y); | ||
} | ||
|
||
display() { | ||
this.edgeDisplays.forEach(edgeDisplay => { | ||
edgeDisplay.display(); | ||
}); | ||
|
||
this.nodeDisplays.forEach(nodeDisplay => { | ||
nodeDisplay.display(); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
This code and its output are licensed under the | ||
Creative Commons Attribution-NonCommercial-NoDerivatives | ||
4.0 International (CC BY-NC-ND 4.0) License. | ||
https://creativecommons.org/licenses/by-nc-nd/4.0/ | ||
*/ | ||
|
||
// Gradient Graphs | ||
// Node Display Class | ||
// Author: Brittni Watkins | ||
|
||
class NodeDisplay { | ||
constructor(positionPercentage, diameter, color) { | ||
this.positionPercentage = positionPercentage.copy(); | ||
this.diameter = diameter; | ||
this.color = color; | ||
this.displayNode = true; | ||
this.pointPercentages = []; | ||
this.buildPoints(); | ||
} | ||
|
||
buildPoints() { | ||
let theta = 0; | ||
let numPoints = 20; | ||
let radius = this.diameter / 2.0; | ||
|
||
for (let i = 0; i < numPoints; i++) { | ||
let baseX = this.positionPercentage.x * width; | ||
let baseY = this.positionPercentage.y * height; | ||
let x = baseX + (cos(theta) * radius); | ||
let y = baseY + (sin(theta) * radius); | ||
let xPercent = x / width; | ||
let yPercent = y / height; | ||
let percentVector = createVector(xPercent, yPercent); | ||
this.pointPercentages.push(percentVector); | ||
theta += TWO_PI / numPoints; | ||
} | ||
} | ||
|
||
getColor() { | ||
return this.color; | ||
} | ||
|
||
toggleDisplayNode() { | ||
this.displayNode = !this.displayNode; | ||
} | ||
|
||
display() { | ||
if (this.displayNode) { | ||
this.displayShape(); | ||
} | ||
} | ||
|
||
displayShape() { | ||
beginShape(); | ||
fill(this.color.getColor()); | ||
noStroke(); | ||
|
||
this.pointPercentages.forEach(point => { | ||
vertex(point.x * width, point.y * height); | ||
}); | ||
|
||
endShape(CLOSE); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
This code and its output are licensed under the | ||
Creative Commons Attribution-NonCommercial-NoDerivatives | ||
4.0 International (CC BY-NC-ND 4.0) License. | ||
https://creativecommons.org/licenses/by-nc-nd/4.0/ | ||
*/ | ||
|
||
// Gradient Graphs | ||
// Edge Class | ||
// Author: Brittni Watkins | ||
|
||
class Edge { | ||
constructor(a, b) { | ||
this.a = a; | ||
this.b = b; | ||
} | ||
|
||
getA() { | ||
return this.a; | ||
} | ||
|
||
getB() { | ||
return this.b; | ||
} | ||
|
||
isEqual(node) { | ||
let equals = false; | ||
|
||
if (node !== null) { | ||
let haveSameNodes = (this.a === node.getA()) && (this.b === node.getB()); | ||
let haveDifferentNodes = (this.a === node.getB()) && (this.b === node.getA()); | ||
equals = haveSameNodes || haveDifferentNodes; | ||
} | ||
|
||
return equals; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
This code and its output are licensed under the | ||
Creative Commons Attribution-NonCommercial-NoDerivatives | ||
4.0 International (CC BY-NC-ND 4.0) License. | ||
https://creativecommons.org/licenses/by-nc-nd/4.0/ | ||
*/ | ||
|
||
// Gradient Graphs | ||
// Gabriel Graph Class | ||
// Author: Brittni Watkins | ||
|
||
class GabrielGraph extends Graph { | ||
constructor(numNodes) { | ||
super(new Scale(createVector(-0.5, -0.5), createVector(0.5, 0.5))); | ||
this.buildNodes(numNodes); | ||
this.initializeAdjacencyLists(); | ||
this.buildAdjacencyList(); | ||
} | ||
|
||
buildNodes(numNodes) { | ||
for (let i = 0; i < numNodes; i++) { | ||
let node = this.buildRandomNode(); | ||
this.nodes.push(node); | ||
} | ||
} | ||
|
||
buildAdjacencyList() { | ||
for (let i = 0; i < this.nodes.length; i++) { | ||
let a = this.nodes[i]; | ||
|
||
for (let j = i + 1; j < this.nodes.length; j++) { | ||
let b = this.nodes[j]; | ||
let hasIntersectingNode = this.hasIntersectingNode(a, b); | ||
|
||
if (!hasIntersectingNode) { | ||
let aAdjacency = this.adjacencyList.get(a); | ||
let bAdjacency = this.adjacencyList.get(b); | ||
aAdjacency.push(b); | ||
bAdjacency.push(a); | ||
} | ||
} | ||
} | ||
|
||
this.buildCompactAdjacencyList(); | ||
this.buildEdges(); | ||
} | ||
|
||
hasIntersectingNode(a, b) { | ||
let hasIntersect = false; | ||
let diameter = Node.getDistance(a, b); | ||
let radius = diameter / 2.0; | ||
let center = Node.getCenterPoint(a, b); | ||
|
||
for (let i = 0; i < this.nodes.length; i++) { | ||
let node = this.nodes[i]; | ||
|
||
if (node !== a && node !== b) { | ||
let nodePosition = node.getPosition(); | ||
let distFromCenter = dist(center.x, center.y, nodePosition.x, nodePosition.y); | ||
|
||
if (distFromCenter < radius) { | ||
hasIntersect = true; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return hasIntersect; | ||
} | ||
} |
Oops, something went wrong.