diff --git a/src/frames/ArrayFrame.java b/src/frames/ArrayFrame.java index 6e62d413..3617f33b 100644 --- a/src/frames/ArrayFrame.java +++ b/src/frames/ArrayFrame.java @@ -185,7 +185,7 @@ public void stateChanged(ChangeEvent event) { int currentLength = ArrayVisualizer.getCurrentLength(); jSlider1.setValue(calculateSliderValue(currentLength)); } - if(ArrayVisualizer.getVisualStyles() == visuals.VisualStyles.CIRCULAR && jSlider1.getValue() == 1) jSlider1.setValue(2); + //if(ArrayVisualizer.getVisualStyles() == visuals.VisualStyles.CIRCULAR && jSlider1.getValue() == 1) jSlider1.setValue(2); Highlights.clearAllMarks(); } diff --git a/src/frames/ImageFrame.java b/src/frames/ImageFrame.java index e4e1ea02..565c877f 100644 --- a/src/frames/ImageFrame.java +++ b/src/frames/ImageFrame.java @@ -15,7 +15,7 @@ import javax.swing.JPanel; import javax.swing.border.EmptyBorder; -import visuals.CustomImage; +import visuals.image.CustomImage; import javax.swing.SwingConstants; public class ImageFrame extends JFrame { diff --git a/src/main/ArrayVisualizer.java b/src/main/ArrayVisualizer.java index 468762ba..d1a3cff3 100644 --- a/src/main/ArrayVisualizer.java +++ b/src/main/ArrayVisualizer.java @@ -43,14 +43,13 @@ import panes.JErrorPane; import threads.RunScriptedSorts; import utils.*; -import visuals.Bars; -import visuals.Circular; -import visuals.CustomImage; -import visuals.Mesh; -import visuals.Pixels; -import visuals.HoopStack; import visuals.Visual; import visuals.VisualStyles; +import visuals.bars.*; +import visuals.circles.*; +import visuals.dots.*; +import visuals.image.*; +import visuals.misc.*; /* * @@ -156,7 +155,6 @@ final public class ArrayVisualizer { private Image img; private Graphics2D mainRender; private Graphics2D extraRender; - private Stroke thickStroke; private Delays Delays; private Highlights Highlights; @@ -351,13 +349,23 @@ public void run() { background.setColor(Color.BLACK); int coltmp = 255; - ArrayVisualizer.this.visualClasses = new Visual[6]; - ArrayVisualizer.this.visualClasses[0] = new Bars(ArrayVisualizer.this); - ArrayVisualizer.this.visualClasses[1] = new Circular(ArrayVisualizer.this); - ArrayVisualizer.this.visualClasses[2] = new CustomImage(ArrayVisualizer.this); - ArrayVisualizer.this.visualClasses[3] = new Mesh(ArrayVisualizer.this); - ArrayVisualizer.this.visualClasses[4] = new Pixels(ArrayVisualizer.this); - ArrayVisualizer.this.visualClasses[5] = new HoopStack(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses = new Visual[15]; + + ArrayVisualizer.this.visualClasses[0] = new BarGraph(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[1] = new Rainbow(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[2] = new DisparityBarGraph(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[3] = new ColorCircle(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[4] = new DisparityCircle(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[5] = new DisparityChords(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[6] = new DisparityDots(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[7] = new ScatterPlot(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[8] = new WaveDots(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[9] = new CustomImage(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[10] = new SineWave(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[11] = new HoopStack(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[12] = new PixelMesh(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[13] = new Spiral(ArrayVisualizer.this); + ArrayVisualizer.this.visualClasses[14] = new SpiralDots(ArrayVisualizer.this); while(ArrayVisualizer.this.visualsEnabled) { if (ArrayVisualizer.this.updateVisualsForced == 0) { @@ -777,19 +785,39 @@ public int windowXCoordinate() { public int windowYCoordinate() { return this.cy; } + + public Color getHighlightColor() { + if(this.colorEnabled()) { + if(this.analysisEnabled()) + return Color.LIGHT_GRAY; + + else + return Color.WHITE; + } + else { + if(this.analysisEnabled()) + return Color.BLUE; + + else + return Color.RED; + } + } public void createVolatileImage() { this.img = this.window.getGraphicsConfiguration().createCompatibleVolatileImage(this.cw, this.ch); } - public void setThickStroke(Stroke stroke) { - this.thickStroke = stroke; - } public Stroke getThickStroke() { - return this.thickStroke; + return new BasicStroke((float) (5 * this.getWindowRatio())); } public Stroke getDefaultStroke() { return new BasicStroke((float) (3 * this.getWindowRatio())); } + public Stroke getThinStroke() { + return new BasicStroke((float) (this.getWindowRatio())); + } + public Stroke getCustomStroke(double size) { + return new BasicStroke((float) (size * this.getWindowRatio())); + } public Graphics2D getMainRender() { return this.mainRender; } @@ -982,8 +1010,8 @@ public void toggleExternalArrays(boolean Bool) { } public void setVisual(VisualStyles choice) { - if(choice == visuals.VisualStyles.CUSTOMIMAGE) { - ((CustomImage) this.visualClasses[2]).enableImgMenu(); + if(choice == visuals.VisualStyles.CUSTOM_IMAGE) { + ((CustomImage) this.visualClasses[9]).enableImgMenu(); } this.VisualStyles = choice; } diff --git a/src/prompts/ViewPrompt.java b/src/prompts/ViewPrompt.java index 074caa29..93179a65 100644 --- a/src/prompts/ViewPrompt.java +++ b/src/prompts/ViewPrompt.java @@ -20,6 +20,7 @@ MIT License Copyright (c) 2019 w0rthy +Copyright (c) 2021 ArrayV 4.0 Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -74,27 +75,29 @@ public void reposition(){ // //GEN-BEGIN:initComponents private void initComponents() { - this.jLabel1 = new javax.swing.JLabel(); + this.jLabel1 = new javax.swing.JLabel(); - this.barGraph = new javax.swing.JButton(); - this.dotGraph = new javax.swing.JButton(); - this.colorCircle = new javax.swing.JButton(); - this.triangleMesh = new javax.swing.JButton(); - this.spiral = new javax.swing.JButton(); - this.disparity = new javax.swing.JButton(); - this.disparityDots = new javax.swing.JButton(); - this.spiralDots = new javax.swing.JButton(); - this.rainbow = new javax.swing.JButton(); - this.customImage = new javax.swing.JButton(); - this.sineWave = new javax.swing.JButton(); - this.waveDots = new javax.swing.JButton(); - this.hoopStack = new javax.swing.JButton();//add later + this.barGraph = new javax.swing.JButton(); + this.dotGraph = new javax.swing.JButton(); + this.colorCircle = new javax.swing.JButton(); + this.pixelMesh = new javax.swing.JButton(); + this.spiral = new javax.swing.JButton(); + this.disparity = new javax.swing.JButton(); + this.disparityDots = new javax.swing.JButton(); + this.spiralDots = new javax.swing.JButton(); + this.rainbow = new javax.swing.JButton(); + this.customImage = new javax.swing.JButton(); + this.sineWave = new javax.swing.JButton(); + this.waveDots = new javax.swing.JButton(); + this.hoopStack = new javax.swing.JButton(); + this.disparityBarGraph = new javax.swing.JButton(); + this.disparityChords = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setResizable(false); jLabel1.setText("Select Visual Style"); - + barGraph.setText("Bar Graph"); barGraph.addActionListener(new java.awt.event.ActionListener() { @Override @@ -119,8 +122,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { } }); - triangleMesh.setText("Triangle Mesh"); - triangleMesh.addActionListener(new java.awt.event.ActionListener() { + pixelMesh.setText("Pixel Mesh"); + pixelMesh.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { triangleMeshActionPerformed(evt); @@ -197,6 +200,22 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { hoopStackActionPerformed(evt); } }); + + disparityBarGraph.setText("Disparity Bar Graph"); + disparityBarGraph.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + disparityBarGraphActionPerformed(evt); + } + }); + + disparityChords.setText("Disparity Chords"); + disparityChords.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + disparityChordsActionPerformed(evt); + } + }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); layout.setHorizontalGroup( @@ -208,7 +227,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(barGraph, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE) .addComponent(rainbow, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE) .addComponent(colorCircle, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE) - .addComponent(disparity, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(disparity, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(disparityBarGraph, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(disparityDots, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE) @@ -218,10 +238,11 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(hoopStack, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.LEADING) - .addComponent(triangleMesh, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE) + .addComponent(pixelMesh, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE) .addComponent(spiral, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE) .addComponent(customImage, GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE) - .addComponent(spiralDots, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(spiralDots, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(disparityChords, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18)) ); layout.setVerticalGroup( @@ -233,7 +254,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(barGraph) .addComponent(disparityDots) - .addComponent(triangleMesh)) + .addComponent(pixelMesh)) .addPreferredGap(ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(rainbow) @@ -251,7 +272,9 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(spiralDots)) .addPreferredGap(ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(Alignment.BASELINE) - .addComponent(hoopStack)) + .addComponent(hoopStack) + .addComponent(disparityBarGraph) + .addComponent(disparityChords)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); getContentPane().setLayout(layout); @@ -267,7 +290,7 @@ private void setAllFieldsFalse(){ ArrayVisualizer.toggleSpiral(false); ArrayVisualizer.toggleWave(false); } - + private void barGraphActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); ArrayVisualizer.setVisual(VisualStyles.BARS); @@ -276,92 +299,91 @@ private void barGraphActionPerformed(java.awt.event.ActionEvent evt) { } private void dotGraphActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.PIXELS); + ArrayVisualizer.setVisual(VisualStyles.DOTS); UtilFrame.jButton2ResetText(); dispose(); } private void rainbowActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.BARS); - ArrayVisualizer.toggleRainbow(true); + ArrayVisualizer.setVisual(VisualStyles.RAINBOW); UtilFrame.jButton2ResetText(); dispose(); } private void triangleMeshActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.MESH); + ArrayVisualizer.setVisual(VisualStyles.PIXEL_MESH); UtilFrame.jButton2ResetText(); dispose(); } private void colorCircleActionPerformed(java.awt.event.ActionEvent evt) { //TODO: Pointer as separate option setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.CIRCULAR); - ArrayVisualizer.togglePointer(true); - ArrayVisualizer.toggleRainbow(true); + ArrayVisualizer.setVisual(VisualStyles.COLOR_CIRCLE); if(ArrayVisualizer.getCurrentLength() == 2) ArrayVisualizer.setCurrentLength(4); UtilFrame.jButton2ResetText(); dispose(); } private void spiralActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.CIRCULAR); - ArrayVisualizer.toggleSpiral(true); + ArrayVisualizer.setVisual(VisualStyles.SPIRAL); if(ArrayVisualizer.getCurrentLength() == 2) ArrayVisualizer.setCurrentLength(4); UtilFrame.jButton2ResetText(); dispose(); } private void disparityActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.CIRCULAR); - ArrayVisualizer.toggleDistance(true); - //ArrayVisualizer.togglePointer(true); + ArrayVisualizer.setVisual(VisualStyles.DISP_CIRCLE); if(ArrayVisualizer.getCurrentLength() == 2) ArrayVisualizer.setCurrentLength(4); UtilFrame.jButton2ResetText(); dispose(); } private void customImageActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.CUSTOMIMAGE); + ArrayVisualizer.setVisual(VisualStyles.CUSTOM_IMAGE); UtilFrame.jButton2ResetText(); dispose(); } private void disparityDotsActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.CIRCULAR); - ArrayVisualizer.toggleDistance(true); - ArrayVisualizer.togglePixels(true); + ArrayVisualizer.setVisual(VisualStyles.DISP_DOTS); if(ArrayVisualizer.getCurrentLength() == 2) ArrayVisualizer.setCurrentLength(4); UtilFrame.jButton2ResetText(); dispose(); } private void spiralDotsActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.CIRCULAR); - ArrayVisualizer.togglePixels(true); - ArrayVisualizer.toggleSpiral(true); + ArrayVisualizer.setVisual(VisualStyles.SPIRAL_DOTS); if(ArrayVisualizer.getCurrentLength() == 2) ArrayVisualizer.setCurrentLength(4); UtilFrame.jButton2ResetText(); dispose(); } private void sineWaveActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.BARS); - ArrayVisualizer.toggleWave(true); + ArrayVisualizer.setVisual(VisualStyles.SINE_WAVE); UtilFrame.jButton2ResetText(); dispose(); } private void waveDotsActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.PIXELS); - ArrayVisualizer.togglePixels(true); - ArrayVisualizer.toggleWave(true); + ArrayVisualizer.setVisual(VisualStyles.WAVE_DOTS); UtilFrame.jButton2ResetText(); dispose(); } private void hoopStackActionPerformed(java.awt.event.ActionEvent evt) { setAllFieldsFalse(); - ArrayVisualizer.setVisual(VisualStyles.HOOPSTACK); + ArrayVisualizer.setVisual(VisualStyles.HOOP_STACK); + UtilFrame.jButton2ResetText(); + dispose(); + } + private void disparityBarGraphActionPerformed(java.awt.event.ActionEvent evt) { + setAllFieldsFalse(); + ArrayVisualizer.setVisual(VisualStyles.DISP_BARS); + UtilFrame.jButton2ResetText(); + dispose(); + } + private void disparityChordsActionPerformed(java.awt.event.ActionEvent evt) { + setAllFieldsFalse(); + ArrayVisualizer.setVisual(VisualStyles.DISP_CHORDS); UtilFrame.jButton2ResetText(); dispose(); } @@ -370,7 +392,7 @@ private void hoopStackActionPerformed(java.awt.event.ActionEvent evt) { private javax.swing.JButton barGraph; private javax.swing.JButton dotGraph; private javax.swing.JButton colorCircle; - private javax.swing.JButton triangleMesh; + private javax.swing.JButton pixelMesh; private javax.swing.JButton spiral; private javax.swing.JButton spiralDots; private javax.swing.JButton disparity; @@ -380,5 +402,7 @@ private void hoopStackActionPerformed(java.awt.event.ActionEvent evt) { private javax.swing.JButton sineWave; private javax.swing.JButton waveDots; private javax.swing.JButton hoopStack; + private javax.swing.JButton disparityBarGraph; + private javax.swing.JButton disparityChords; private javax.swing.JLabel jLabel1; } \ No newline at end of file diff --git a/src/utils/Renderer.java b/src/utils/Renderer.java index 11ea1549..6fc8f6ed 100644 --- a/src/utils/Renderer.java +++ b/src/utils/Renderer.java @@ -1,7 +1,5 @@ package utils; -import java.awt.BasicStroke; - import main.ArrayVisualizer; import visuals.VisualStyles; @@ -73,7 +71,6 @@ final public class Renderer { public Renderer(ArrayVisualizer ArrayVisualizer) { ArrayVisualizer.setWindowHeight(); ArrayVisualizer.setWindowWidth(); - ArrayVisualizer.setThickStroke(new BasicStroke(8)); } public double getXScale() { diff --git a/src/visuals/Bars.java b/src/visuals/Bars.java deleted file mode 100644 index 1827d6e6..00000000 --- a/src/visuals/Bars.java +++ /dev/null @@ -1,120 +0,0 @@ -package visuals; - -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class Bars extends Visual { - public Bars(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for(int i = 0; i < Renderer.getArrayLength(); i++){ - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - if (width == 0) continue; - - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.GREEN); - } - else if(ArrayVisualizer.rainbowEnabled() || ArrayVisualizer.colorEnabled()) { - int val = (ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled()) ? ArrayVisualizer.getIndexValue(array[i]) : array[i]; - this.mainRender.setColor(getIntColor(val, Renderer.getArrayLength())); - } - else this.mainRender.setColor(Color.WHITE); - - drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled()); - } - else { - if(ArrayVisualizer.rainbowEnabled() || ArrayVisualizer.colorEnabled()) { - int val = (ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled()) ? ArrayVisualizer.getIndexValue(array[i]) : array[i]; - this.mainRender.setColor(getIntColor(val, Renderer.getArrayLength())); - //if(array[i] > -1) this.mainRender.setColor(getIntColor(ArrayVisualizer.getShadowArray()[array[i]], Renderer.getArrayLength())); - } - else this.mainRender.setColor(Color.WHITE); - - if(Renderer.getArrayLength() != 2) { - colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled()); - } - } - /* - int markHeight = 0; - Color currentColor = mainRender.getColor(); - if(currentColor == Color.BLACK || currentColor == Color.RED || currentColor == Color.BLUE) { - markHeight = 5; - } - */ - - int y = 0; - - if(ArrayVisualizer.rainbowEnabled()) { - this.mainRender.fillRect(Renderer.getOffset() + 20, Renderer.getYOffset(), width, Renderer.getViewSize()); - - Renderer.setOffset(Renderer.getOffset() + width); - } - else if(ArrayVisualizer.waveEnabled()) { - y = (int) ((Renderer.getViewSize() / 4) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize()); - this.mainRender.fillRect(Renderer.getOffset() + 20, Renderer.getYOffset() + y, width, 20); - Renderer.setOffset(Renderer.getOffset() + width); - } - else { - /* - int gap = 0; - if(width > 5) { - gap = 5; - } - */ - - int val = (ArrayVisualizer.doingStabilityCheck() && ArrayVisualizer.colorEnabled()) ? ArrayVisualizer.getStabilityValue(array[i]) : array[i]; - y = (int) (((Renderer.getViewSize() - 20)) - (val + 1) * Renderer.getYScale()); - mainRender.fillRect(Renderer.getOffset() + 20, Renderer.getYOffset() + y, width, (int) ((val + 1) * Renderer.getYScale())); - - //mainRender.fillRect(Renderer.getOffset() + 20, y /*- markHeight*/, width /*- gap*/, (int) ((array[i] + 1) * Renderer.getYScale()) /*+ markHeight*/); - - /* - double thickness = 1; - Stroke oldStroke = mainRender.getStroke(); - mainRender.setStroke(new BasicStroke((float) thickness)); - mainRender.setColor(Color.BLACK); - mainRender.drawLine(Renderer.getOffset() + 20, y, Renderer.getOffset() + 20, (int) Math.max(array[i] * Renderer.getYScale()-1, 1) + y); - mainRender.setStroke(oldStroke); - */ - Renderer.setOffset(Renderer.getOffset() + width); - } - } - if (ArrayVisualizer.externalArraysEnabled() && !ArrayVisualizer.rainbowEnabled()) { - this.mainRender.setColor(Color.BLUE); - this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); - } - } -} \ No newline at end of file diff --git a/src/visuals/Circular.java b/src/visuals/Circular.java deleted file mode 100644 index 5f6c6c0a..00000000 --- a/src/visuals/Circular.java +++ /dev/null @@ -1,301 +0,0 @@ -package visuals; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Polygon; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy -Copyright (c) 2020 aphitorite - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class Circular extends Visual { - final private static double CIRC_HEIGHT_RATIO = 45 / 18d; - final private static double CIRC_WIDTH_RATIO = 80 / 18d; - - final private static double PNT_HEIGHT_RATIO = 45 / 19d; - final private static double PNT_WIDTH_RATIO = 80 / 19d; - - public Circular(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - // The reason we use cosine with height (expressed in terms of y) and sine with width (expressed in terms of x) is because our circles are rotated 90 degrees. - // After that rotation, sine is on the x-axis and cosine is on the y-axis. - - // If we we use sine with height and cosine with width, the sorts would start from the right side of the circle, - // just like the unit circle from trigonometry. - - private static double getSinOfDegrees(double d, int halfCirc) { - return Math.sin((d * Math.PI) / halfCirc); - } - - private static double getCosOfDegrees(double d, int halfCirc) { - return Math.cos((d * Math.PI) / halfCirc); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - if (Renderer.auxActive) - return; - - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){ - if(i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.getHSBColor((1f/3f), 1f, 0.8f)); - } - else if(!ArrayVisualizer.colorEnabled() && (ArrayVisualizer.spiralEnabled() || ArrayVisualizer.distanceEnabled() || ArrayVisualizer.pixelsEnabled())) { - this.mainRender.setColor(Color.WHITE); - } - else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - //else this.mainRender.setColor(getIntColor(ArrayVisualizer.getShadowArray()[array[i]], ArrayVisualizer.getCurrentLength())); - - if(Highlights.fancyFinishActive()) { - drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled()); - } - else { - if(ArrayVisualizer.pointerActive()) { - if(Highlights.containsPosition(i)) { - if(ArrayVisualizer.analysisEnabled()) { - this.extraRender.setColor(Color.GRAY); - } - else { - this.extraRender.setColor(Color.WHITE); - } - - int pointerSize = 10; - if(ArrayVisualizer.getCurrentLength() < 2048) { - int multiple = ArrayVisualizer.getCurrentLength(); - do { - pointerSize += 5; - } while((multiple *= 2) < 2048); - } - - //Create new Polygon for the pointer - Polygon pointer = new Polygon(); - - //Calculate radians - double degrees = 360 * ((double) i / ArrayVisualizer.getCurrentLength()); - double radians = Math.toRadians(degrees); - - int pointerWidthRatio = ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(((i + (i + 1)) / 2d), ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.currentWidth() - 64) / PNT_WIDTH_RATIO)); - int pointerHeightRatio = ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(((i + (i + 1)) / 2d), ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowHeight() - 96) / PNT_HEIGHT_RATIO)); - - //First step: draw a triangle - int[] pointerXValues = {pointerWidthRatio - pointerSize, - pointerWidthRatio, - pointerWidthRatio + pointerSize}; - - int[] pointerYValues = {pointerHeightRatio - (10 + (pointerSize - 10)), - pointerHeightRatio + 10, - pointerHeightRatio - (10 + (pointerSize - 10))}; - - //Second step: rotate triangle (https://en.wikipedia.org/wiki/Rotation_matrix) - for(int j = 0; j < pointerXValues.length; j++) { - double x = pointerXValues[j] - pointerWidthRatio; - double y = pointerYValues[j] - pointerHeightRatio; - - pointerXValues[j] = (int) (pointerWidthRatio - + x*Math.cos(radians) - - y*Math.sin(radians)); - pointerYValues[j] = (int) (pointerHeightRatio - + x*Math.sin(radians) - + y*Math.cos(radians)); - } - - for(int j = 0; j < pointerXValues.length; j++) { - pointer.addPoint(pointerXValues[j], pointerYValues[j]); - } - - this.extraRender.fillPolygon(pointer); - } - } - else if(ArrayVisualizer.getCurrentLength() != 2){ - colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - } - } - - if(ArrayVisualizer.distanceEnabled()) { - //TODO: Rewrite this abomination - //double len = ((ArrayVisualizer.getCurrentLength() / 2d) - Math.min(Math.min(Math.abs(i - array[i]), Math.abs(i - array[i] + ArrayVisualizer.getCurrentLength())), Math.abs(i - array[i] - ArrayVisualizer.getCurrentLength()))) / (ArrayVisualizer.getCurrentLength() / 2d); - - // Both formulas written by aphitorite (https://github.com/aphitorite) - // Original triangle wave formula, rewritten - // double len = 2 * Math.abs(Math.abs(array[i] - i) - ArrayVisualizer.getCurrentLength() * 0.5) / ArrayVisualizer.getCurrentLength(); - - // Cosine formula - double len = (1 + Math.cos((Math.PI * (array[i] - i)) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; - - if(ArrayVisualizer.pixelsEnabled()) { - int linkedpixX = ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowWidth() - 64) / CIRC_WIDTH_RATIO * len)) + Renderer.getDotWidth() / 2; - int linkedpixY = ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowHeight() - 96) / CIRC_HEIGHT_RATIO * len)) + Renderer.getDotHeight() / 2; - - if(ArrayVisualizer.linesEnabled()) { - if(i > 0) { - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - lineFancy(this.mainRender, ArrayVisualizer.currentWidth()); - } - else { - lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - } - - drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled()); - } - else { - if(Highlights.containsPosition(i)) { - lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - } - this.mainRender.drawLine(linkedpixX, linkedpixY, Renderer.getLineX(), Renderer.getLineY()); - } - Renderer.setLineX(linkedpixX); - Renderer.setLineY(linkedpixY); - } - else { - boolean drawRect = false; - if(Highlights.containsPosition(i)) { - setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - drawRect = true; - } - - if(drawRect) { - this.extraRender.setStroke(ArrayVisualizer.getThickStroke()); - if(Highlights.fancyFinishActive()) { - this.extraRender.fillRect((linkedpixX - Renderer.getDotWidth() / 2) - 10, (linkedpixY - Renderer.getDotHeight() / 2) - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20); - } - else { - this.extraRender.drawRect((linkedpixX - Renderer.getDotWidth() / 2) - 10, (linkedpixY - Renderer.getDotHeight() / 2) - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20); - } - this.extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f))); - } - this.mainRender.fillRect(linkedpixX - Renderer.getDotWidth() / 2, linkedpixY - Renderer.getDotHeight() / 2, Renderer.getDotWidth(), Renderer.getDotHeight()); - } - } - else { - Polygon p = new Polygon(); - - p.addPoint(ArrayVisualizer.windowHalfWidth(), - ArrayVisualizer.windowHalfHeight()); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * (((ArrayVisualizer.currentWidth() - 64) / CIRC_WIDTH_RATIO) * len)), - ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * (((ArrayVisualizer.currentHeight() - 96) / CIRC_HEIGHT_RATIO) * len))); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * (((ArrayVisualizer.currentWidth() - 64) / CIRC_WIDTH_RATIO) * len)), - ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * (((ArrayVisualizer.currentHeight() - 96) / CIRC_HEIGHT_RATIO) * len))); - - this.mainRender.fillPolygon(p); - } - } - else if(ArrayVisualizer.spiralEnabled()) { - if(ArrayVisualizer.pixelsEnabled()) { - if(ArrayVisualizer.linesEnabled()) { - if(i > 0) { - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - lineFancy(this.mainRender, ArrayVisualizer.currentWidth()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - - drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled()); - } - else { - if(Highlights.containsPosition(i)) { - lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - } - this.mainRender.drawLine(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[i]) / ArrayVisualizer.getCurrentLength())), - ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[i]) / ArrayVisualizer.getCurrentLength())), - Renderer.getLineX(), - Renderer.getLineY()); - } - Renderer.setLineX(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[i]) / ArrayVisualizer.getCurrentLength()))); - Renderer.setLineY(ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[i]) / ArrayVisualizer.getCurrentLength()))); - } - else { - boolean drawRect = false; - if(Highlights.containsPosition(i)) { - setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - drawRect = true; - } - - int rectx = ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * (((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[i]) / ArrayVisualizer.getCurrentLength()))); - int recty = ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * (((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[i]) / ArrayVisualizer.getCurrentLength()))); - - this.mainRender.fillRect(rectx, recty, Renderer.getDotWidth(), Renderer.getDotHeight()); - - if(drawRect) { - this.extraRender.setStroke(ArrayVisualizer.getThickStroke()); - if(Highlights.fancyFinishActive()) { - this.extraRender.fillRect(rectx - 10, recty - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20); - } - else { - this.extraRender.drawRect(rectx - 10, recty - 10, Renderer.getDotWidth() + 20, Renderer.getDotHeight() + 20); - } - this.extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f))); - } - } - } - else { - if(Highlights.containsPosition(i)) { - markBar(this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled()); - } - - Polygon p = new Polygon(); - - p.addPoint(ArrayVisualizer.windowHalfWidth(), - ArrayVisualizer.windowHalfHeight()); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[i]) / ArrayVisualizer.getCurrentLength())), - ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[i]) / ArrayVisualizer.getCurrentLength()))); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowWidth() - 64) / 3.0) * array[Math.min(i + 1, ArrayVisualizer.getCurrentLength() - 1)]) / ArrayVisualizer.getCurrentLength())), - ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((((ArrayVisualizer.windowHeight() - 96) / 2.0) * array[Math.min(i + 1, ArrayVisualizer.getCurrentLength() - 1)]) / ArrayVisualizer.getCurrentLength()))); - - this.mainRender.fillPolygon(p); - } - } - else { - Polygon p = new Polygon(); - - p.addPoint(ArrayVisualizer.windowHalfWidth(), - ArrayVisualizer.windowHalfHeight()); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowWidth() - 64) / CIRC_WIDTH_RATIO)), - ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowHeight() - 96) / CIRC_HEIGHT_RATIO))); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (Circular.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowWidth() - 64) / CIRC_WIDTH_RATIO)), - ArrayVisualizer.windowHalfHeight() - (int) (Circular.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowHeight() - 96) / CIRC_HEIGHT_RATIO))); - - this.mainRender.fillPolygon(p); - } - } - } -} \ No newline at end of file diff --git a/src/visuals/CircularBackup2.java b/src/visuals/CircularBackup2.java deleted file mode 100644 index 47106a56..00000000 --- a/src/visuals/CircularBackup2.java +++ /dev/null @@ -1,227 +0,0 @@ -package visuals; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Polygon; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy -Copyright (c) 2020 aphitorite - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class CircularBackup2 extends Visual { - final private static double CIRC_HEIGHT_RATIO = 45 / 18d; - final private static double CIRC_WIDTH_RATIO = 80 / 18d; - - final private static double PNT_HEIGHT_RATIO = 45 / 19d; - final private static double PNT_WIDTH_RATIO = 80 / 19d; - - final private static Color fancyGray = new Color(0, 0, 0, .5f); - final private static Color fancyGreen = Color.getHSBColor((1f/3f), 1f, 0.8f); - - final private static Color analysisBlue = new Color(0, 0, 1, .5f); - - private int pointerSize = 10; - private int storedLength = 2048; - private int storedLengthLog = 11; - - private int storedWindowHeight; - private int storedWindowWidth; - - private double circleHeightFactor; - private double circleWidthFactor; - - private double pointerHeightFactor; - private double pointerWidthFactor; - - public CircularBackup2(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - this.processNewArraySize(ArrayVisualizer); - this.processNewWindowHeight(ArrayVisualizer); - this.processNewWindowWidth(ArrayVisualizer); - } - - // The reason we use cosine with height (expressed in terms of y) and sine with width (expressed in terms of x) is because our circles are rotated 90 degrees. - // After that rotation, sine is on the x-axis and cosine is on the y-axis. - - // If we we use sine with height and cosine with width, the sorts would start from the right side of the circle, - // just like the unit circle from trigonometry. - - private static double getSinOfDegrees(double d, int halfCirc) { - return Math.sin((d * Math.PI) / halfCirc); - } - - private static double getCosOfDegrees(double d, int halfCirc) { - return Math.cos((d * Math.PI) / halfCirc); - } - - private void processNewArraySize(ArrayVisualizer ArrayVisualizer) { - this.storedLengthLog = ArrayVisualizer.getLogBaseTwoOfLength(); - this.storedLength = ArrayVisualizer.getCurrentLength(); - - this.pointerSize = 10; - if(this.storedLength < 2048) { - int multiple = this.storedLength; - do { - this.pointerSize += 5; - } while((multiple *= 2) < 2048); - } - } - - private void processNewWindowHeight(ArrayVisualizer ArrayVisualizer) { - int modifiedHeight = ArrayVisualizer.windowHeight() - 96; - this.circleHeightFactor = modifiedHeight / CIRC_HEIGHT_RATIO; - this.pointerHeightFactor = modifiedHeight / PNT_HEIGHT_RATIO; - this.storedWindowHeight = ArrayVisualizer.windowHeight(); - } - - private void processNewWindowWidth(ArrayVisualizer ArrayVisualizer) { - int modifiedWidth = ArrayVisualizer.windowWidth() - 64; - this.circleWidthFactor = modifiedWidth / CIRC_WIDTH_RATIO; - this.pointerWidthFactor = modifiedWidth / PNT_WIDTH_RATIO; - this.storedWindowWidth = ArrayVisualizer.windowWidth(); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - if(ArrayVisualizer.getCurrentLength() != this.storedLength) { - this.processNewArraySize(ArrayVisualizer); - } - - if(this.storedWindowHeight != ArrayVisualizer.windowHeight()) { - this.processNewWindowHeight(ArrayVisualizer); - } - - if(this.storedWindowWidth != ArrayVisualizer.windowWidth()) { - this.processNewWindowWidth(ArrayVisualizer); - } - - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) { - if(!Highlights.fancyFinishActive()) { - if(Highlights.containsPosition(i)) { - this.extraRender.setColor(Color.WHITE); - if(ArrayVisualizer.analysisEnabled()) { - this.extraRender.setColor(analysisBlue); - } - - double pointerSin = CircularBackup2.getSinOfDegrees(((i + (i + 1)) / 2d), ArrayVisualizer.halfCircle()); - double pointerCos = CircularBackup2.getCosOfDegrees(((i + (i + 1)) / 2d), ArrayVisualizer.halfCircle()); - - //Create new Polygon for the pointer - Polygon pointer = new Polygon(); - - int pointerWidthRatio = ArrayVisualizer.windowHalfWidth() + (int) (pointerSin * this.pointerWidthFactor); - int pointerHeightRatio = ArrayVisualizer.windowHalfHeight() - (int) (pointerCos * this.pointerHeightFactor); - - //First step: draw a triangle - int[] pointerXValues = {pointerWidthRatio - pointerSize, - pointerWidthRatio, - pointerWidthRatio + pointerSize}; - - int[] pointerYValues = {pointerHeightRatio - (10 + (pointerSize - 10)), - pointerHeightRatio + 10, - pointerHeightRatio - (10 + (pointerSize - 10))}; - - //Second step: rotate triangle (https://en.wikipedia.org/wiki/Rotation_matrix) - for(int j = 0; j < pointerXValues.length; j++) { - double x = pointerXValues[j] - pointerWidthRatio; - double y = pointerYValues[j] - pointerHeightRatio; - - pointerXValues[j] = (int) (pointerWidthRatio - + x * pointerCos - - y * pointerSin); - pointerYValues[j] = (int) (pointerHeightRatio - + x * pointerSin - + y * pointerCos); - } - - //Third step: redraw triangle coordinates on (x, y) plane - for(int j = 0; j < pointerXValues.length; j++) { - pointer.addPoint(pointerXValues[j], pointerYValues[j]); - } - - //Fourth step: Fill it in! - this.extraRender.fillPolygon(pointer); - } - } - - this.extraRender.setColor(Color.WHITE); - this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - - if(Highlights.fancyFinishActive()) { - int position = Highlights.getFancyFinishPosition(); - if(i < position) { - /* - * GOOD replacement for - * switch(this.storedLengthLog) { - case 14: if(i == position - 13) this.extraRender.setColor(fancyRed); - case 13: if(i == position - 12) this.extraRender.setColor(fancyRed); - case 12: if(i == position - 11) this.extraRender.setColor(fancyRed); - case 11: if(i == position - 10) this.extraRender.setColor(fancyRed); - case 10: if(i == position - 9) this.extraRender.setColor(fancyRed); - case 9: if(i == position - 8) this.extraRender.setColor(fancyRed); - case 8: if(i == position - 7) this.extraRender.setColor(fancyRed); - case 7: if(i == position - 6) this.extraRender.setColor(fancyRed); - case 6: if(i == position - 5) this.extraRender.setColor(fancyRed); - case 5: if(i == position - 4) this.extraRender.setColor(fancyRed); - case 4: if(i == position - 3) this.extraRender.setColor(fancyRed); - case 3: if(i == position - 2) this.extraRender.setColor(fancyRed); - case 2: if(i == position - 1) this.extraRender.setColor(fancyRed); - default: if(i == position) this.extraRender.setColor(fancyRed); - } - */ - if(i > (position - this.storedLengthLog)) { - this.extraRender.setColor(fancyGray); - } - else { - this.mainRender.setColor(fancyGreen); - } - } - } - - Polygon p = new Polygon(); - - p.addPoint(ArrayVisualizer.windowHalfWidth(), - ArrayVisualizer.windowHalfHeight()); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (CircularBackup2.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * this.circleWidthFactor), - ArrayVisualizer.windowHalfHeight() - (int) (CircularBackup2.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * this.circleHeightFactor)); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (CircularBackup2.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * this.circleWidthFactor), - ArrayVisualizer.windowHalfHeight() - (int) (CircularBackup2.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * this.circleHeightFactor)); - - this.mainRender.fillPolygon(p); - - if(this.extraRender.getColor().equals(fancyGray)) { - Polygon e = p; - this.extraRender.fillPolygon(e); - } - } - } -} \ No newline at end of file diff --git a/src/visuals/CustomImage.java b/src/visuals/CustomImage.java deleted file mode 100644 index 459b8527..00000000 --- a/src/visuals/CustomImage.java +++ /dev/null @@ -1,385 +0,0 @@ -package visuals; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import java.awt.image.AffineTransformOp; -import java.awt.image.BufferedImage; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.IOException; - -import javax.imageio.ImageIO; -import javax.swing.JFrame; - -import dialogs.CustomImageDialog; -import dialogs.LoadingDialog; -import dialogs.SoundbankDialog; -import frames.ImageFrame; -import main.ArrayVisualizer; -import panes.JErrorPane; -import resources.image.ImgFetcher; -import utils.Highlights; -import utils.Renderer; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy -Copyright (c) 2020 aphitorite - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -/* - * CustomImage visual and sort bar graph artwork (image/pic.jpg) created by - * aphitorite (https://github.com/aphitorite/ArrayVisualizer) - */ -final public class CustomImage extends Visual { - public static CustomImage visual; - - private volatile BufferedImage img; - private volatile int imgHeight; - private volatile int imgWidth; - - private boolean imgImported; - private boolean imgScaled; - private boolean openImgMenu; - - private int windowHeight; - private int windowWidth; - - private volatile ImageFrame pictureMenu; - private volatile LoadingDialog infoMsg; - - final private String defaultArtwork = "Summer Sorting by aphitorite"; - private String currentImage; - private File imageFile; - - public CustomImage(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - CustomImage.visual = this; - this.imgImported = false; // Don't load the image unless the user selects the - // 'Custom Image' visual. Program initially boots up - // faster this way. - this.enableImgMenu(); - this.updateWindowDims(ArrayVisualizer); - this.currentImage = this.defaultArtwork; - } - - public BufferedImage getImage() { - return this.img; - } - public int getImgHeight() { - return this.imgHeight; - } - public int getImgWidth() { - return this.imgWidth; - } - - public String getCurrentImageName() { - return this.currentImage; - } - - public void enableImgMenu() { - this.openImgMenu = true; - } - - private void updateImageDims() throws Exception { - this.imgHeight = this.img.getHeight(); - this.imgWidth = this.img.getWidth(); - } - - private void updateWindowDims(ArrayVisualizer ArrayVisualizer) { - this.windowHeight = ArrayVisualizer.windowHeight(); - this.windowWidth = ArrayVisualizer.windowWidth(); - } - - private void refreshCustomImage(ImageFrame menu) { - menu.dispose(); - this.imgImported = false; - this.imgScaled = false; - this.openImgMenu = true; - } - - public void loadDefaultArtwork(ImageFrame menu) { - this.currentImage = this.defaultArtwork; - this.refreshCustomImage(menu); - } - public void loadCustomImage(ImageFrame menu) { - CustomImageDialog dialog = new CustomImageDialog(); - this.imageFile = dialog.getFile(); - if(this.imageFile != null) { - this.currentImage = this.imageFile.getName(); - this.refreshCustomImage(menu); - } - } - public void loadCustomImage(File file) { - this.imageFile = file; - if(this.imageFile != null) { - this.currentImage = this.imageFile.getName(); - this.refreshCustomImage(ImageFrame.defaultFrame); - } - } - - @SuppressWarnings("unused") - private boolean fetchBufferedImage(boolean showInfoMsg, JFrame window) { - // New copy of image being imported; has not been scaled yet - this.imgScaled = false; - - boolean defaultImage = this.currentImage.equals(this.defaultArtwork); - - if(showInfoMsg) { - String message; - if(defaultImage) { - message = "resources/image/pic.jpg"; - } - else { - message = this.currentImage; - } - this.infoMsg = new LoadingDialog(message, window); - } - - boolean success = true; - - ImgFetcher imgFetcher; - if(defaultImage) { - imgFetcher = new ImgFetcher(); - } - else { - imgFetcher = new ImgFetcher(this.imageFile); - } - BufferedInputStream stream = imgFetcher.getStream(); - - try { - this.img = ImageIO.read(stream); - } - catch (IOException e) { - success = false; - JErrorPane.invokeErrorMessage(e); - } - catch (IllegalArgumentException e) { - success = false; - if(defaultImage) { - JErrorPane.invokeCustomErrorMessage("image/pic.jpg missing: Couldn't find the default image for the program's 'Custom Image' visual!"); - } - else { - JErrorPane.invokeCustomErrorMessage(this.currentImage + " missing: ArrayV couldn't find your picture at the given location!"); - } - } - finally { - try { - stream.close(); - } - catch (NullPointerException e) { - success = false; // A NullPointerException means a null stream, which would have already thrown an IllegalArgumentException - } - catch (Exception e) { - success = false; - JErrorPane.invokeErrorMessage(e); - } - } - - // Update the image dimensions. If this fails, the file wasn't a proper image - if(success) { - try { - this.updateImageDims(); - } - catch (Exception e) { - success = false; - if(defaultImage) { - JErrorPane.invokeCustomErrorMessage("image/pic.jpg invalid or corrupt: The file for the program's 'Custom Image' visual was not recognized as a valid image!"); - } - else { - JErrorPane.invokeCustomErrorMessage(this.currentImage + " invalid or corrupt: Your picture was not recognized as a valid image!"); - } - } - } - - if(showInfoMsg) { - this.infoMsg.closeDialog(); - } - - if(!success) { - // If loading a custom file didn't work, then try loading the default artwork instead. - if(!defaultImage) { - this.currentImage = this.defaultArtwork; - return this.fetchBufferedImage(true, window); - } - else { - return false; - } - } - else { - return true; - } - } - - // Many thanks to Jörn Horstmann for providing fast image scaling code. - // https://stackoverflow.com/questions/3967731/how-to-improve-the-performance-of-g-drawimage-method-for-resizing-images/3967988#3967988 - @SuppressWarnings("unused") - private boolean getScaledImage(int width, int height) throws Exception { - boolean success = true; - - // Only fetch a fresh copy of the image if it's been previously scaled. - if(this.imgScaled) { - if(!this.fetchBufferedImage(false, null)) { - throw new Exception(); - } - } - - double scaleX = (double) width / this.imgWidth; - double scaleY = (double) height / this.imgHeight; - AffineTransform scaleTransform = AffineTransform.getScaleInstance(scaleX, scaleY); - AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BICUBIC); - - try { - this.img = bilinearScaleOp.filter(this.img, new BufferedImage(width, height, this.img.getType())); - - /* - * We don't want to resize the cached copy of the image more than once as the quality degrades quickly. - * Therefore, keep track of the image being scaled so we can import a fresh copy the next time the window - * is resized. - */ - this.imgScaled = true; - - this.updateImageDims(); - } - catch (IllegalArgumentException e) { - JErrorPane.invokeCustomErrorMessage("CustomImage.getScaledImage() was called even though the image's dimensions haven't changed!"); - } - catch (Exception e) { - success = false; - JErrorPane.invokeErrorMessage(e); - } - - return success; - } - - public static void markCustomBar(ArrayVisualizer ArrayVisualizer, Graphics2D bar, Renderer Renderer, int width, boolean analysis) { - if(analysis) { - bar.setColor(new Color(0, 0, 1, .5f)); - } - else { - bar.setColor(new Color(1, 0, 0, .5f)); - } - bar.fillRect(Renderer.getOffset() + 20, 0, width, ArrayVisualizer.windowHeight()); - } - - @SuppressWarnings("fallthrough") - //The longer the array length, the more bars marked. Makes the visual easier to see when bars are thinner. - public static void colorCustomBars(int logOfLen, int index, Highlights Highlights, ArrayVisualizer ArrayVisualizer, Graphics2D bar, Renderer Renderer, int width, boolean analysis) { - switch(logOfLen) { - case 15: if(Highlights.containsPosition(index - 15)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 14)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 13)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 12)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 11)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - case 14: if(Highlights.containsPosition(index - 10)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 9)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 8)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - case 13: if(Highlights.containsPosition(index - 7)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 6)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 5)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - case 12: if(Highlights.containsPosition(index - 4)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - if(Highlights.containsPosition(index - 3)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - case 11: if(Highlights.containsPosition(index - 2)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - case 10: if(Highlights.containsPosition(index - 1)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } - default: if(Highlights.containsPosition(index)) markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); - } - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - if (Renderer.auxActive) - return; - - try { - /* - * Load the image on first use of the 'Custom Image' visual or if the program failed to read the image file previously. - * Gives debuggers the ability to try another file without having to restart the program. This also is a safe way of - * handling exceptions whenever the user clicks the 'Custom Image' button. - */ - if(!this.imgImported) { - if(!this.fetchBufferedImage(true, ArrayVisualizer.getMainWindow())) { - throw new Exception(); - } - else { - this.imgImported = true; - } - } - /* - * Use a fast image scaling method if the window was resized. If an ImagingOpException is thrown, don't continue with - * the 'Custom Image' visual. - */ - if(this.windowHeight != ArrayVisualizer.currentHeight() || this.windowWidth != ArrayVisualizer.currentWidth()) { - if(!this.getScaledImage(ArrayVisualizer.currentWidth(), ArrayVisualizer.currentHeight())) { - throw new Exception(); - } - this.updateWindowDims(ArrayVisualizer); - } - - if(this.openImgMenu) { - this.pictureMenu = new ImageFrame(this); - this.pictureMenu.setVisible(true); - this.pictureMenu.updatePreview(this); - this.openImgMenu = false; - } - } - catch (Exception e) { - JErrorPane.invokeErrorMessage(e); - ArrayVisualizer.setVisual(visuals.VisualStyles.BARS); - return; - } - - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) { - int width = (int) (Renderer.getXScale() * (i + 1) - Renderer.getOffset()); - if (width == 0) continue; - - //Cuts the image in respect to each item in the array - this.mainRender.drawImage( - this.img, - - Renderer.getOffset() + 20, - 0, - Renderer.getOffset() + 20 + width, - ArrayVisualizer.windowHeight(), - - (int) ((double) this.imgWidth / ArrayVisualizer.getCurrentLength() * array[i]), - 0, - (int) Math.ceil((double) this.imgWidth / ArrayVisualizer.getCurrentLength() * (array[i] + 1)), - this.imgHeight, - - null - ); - - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - this.extraRender.setColor(new Color(0, 1, 0, .5f)); - this.extraRender.fillRect(Renderer.getOffset() + 20, 0, width, ArrayVisualizer.windowHeight()); - } - } - else CustomImage.colorCustomBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, ArrayVisualizer, this.extraRender, Renderer, width, ArrayVisualizer.analysisEnabled()); - - Renderer.setOffset(Renderer.getOffset() + width); - } - } -} \ No newline at end of file diff --git a/src/visuals/Mesh.java b/src/visuals/Mesh.java deleted file mode 100644 index 121b6b51..00000000 --- a/src/visuals/Mesh.java +++ /dev/null @@ -1,139 +0,0 @@ -package visuals; - -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class Mesh extends Visual { - public Mesh(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - //TODO: Change these to be more consistent between array lengths. These heights and counts are a bit random. - public static int getTriangleHeight(int length, double height) { - switch(length) { - case 2: height *= 20; break; - case 4: height *= 13; break; - case 16: - case 32: height *= 4.4; break; - case 64: height *= 2.3; break; - case 128: height *= 2.35; break; - case 256: height *= 1.22; break; - default: height *= 1; - } - - return (int) height; - } - - public static int getTrianglesPerRow(int length, int trianglesPerColumn) { - int trianglesPerRow; - - switch(length) { - case 32: - case 64: trianglesPerRow = 4; break; - case 128: - case 256: trianglesPerRow = 8; break; - default: trianglesPerRow = Math.max(length / trianglesPerColumn, 2); - } - - return trianglesPerRow; - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - if (Renderer.auxActive) - return; - - int trih = getTriangleHeight(ArrayVisualizer.getCurrentLength(), ArrayVisualizer.windowHeight() / 20); //Height of triangles to use, Width will be scaled accordingly - - int tripercol = (ArrayVisualizer.windowHeight() / trih) * 2; //Triangles per column - int triperrow = getTrianglesPerRow(ArrayVisualizer.getCurrentLength(), tripercol); //Triangles per row - - double triw = (double) ArrayVisualizer.windowWidth() / triperrow; //Width of triangles to use - - double curx = 0; - int cury = 15; - - int[] triptsx = new int[3]; - int[] triptsy = new int[3]; - - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){ - if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() > 8) { - if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.WHITE); - else this.mainRender.setColor(Color.BLACK); - } - else { - //TODO: Clean up this visual trick - if(Highlights.fancyFinishActive() && (i < Highlights.getFancyFinishPosition() && i > Highlights.getFancyFinishPosition() - ArrayVisualizer.getLogBaseTwoOfLength())) { - this.mainRender.setColor(Color.GREEN); - } - else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - } - //If i/triperrow is even, then triangle points right, else left - boolean direction = false; - if((i / triperrow) % 2 == 0) direction = true; - else direction = false; - - //Make the triangle - if(!direction) { - //Pointing right - triptsx[0] = (int) curx; - triptsx[1] = (int) curx; - curx += triw; - triptsx[2] = (int) curx; - - triptsy[0] = cury; - triptsy[2] = cury + (trih / 2); - triptsy[1] = cury + trih; - }else{ - //Pointing left - triptsx[2] = (int) curx; - curx += triw; - triptsx[0] = (int) curx; - triptsx[1] = (int) curx; - - triptsy[0] = cury; - triptsy[2] = cury + (trih / 2); - triptsy[1] = cury + trih; - } - - //Draw it - this.mainRender.fillPolygon(triptsx, triptsy, triptsx.length); - - //If at the end of a row, reset curx - //(i != 0 || i != currentLen - 1) - if((i + 1) % triperrow == 0){ - curx = 0; - cury += trih / 2; - } - } - } -} \ No newline at end of file diff --git a/src/visuals/Pixels.java b/src/visuals/Pixels.java deleted file mode 100644 index 9596f789..00000000 --- a/src/visuals/Pixels.java +++ /dev/null @@ -1,147 +0,0 @@ -package visuals; - -import java.awt.BasicStroke; -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class Pixels extends Visual { - public Pixels(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - if(ArrayVisualizer.linesEnabled()) { - //TODO: Wave visual needs to be *heavily* refactored - if(ArrayVisualizer.waveEnabled()) { - Renderer.setLineY((int) ((Renderer.getViewSize() / 4) * Math.sin((2 * Math.PI * ((double) array[1] / Renderer.getArrayLength()))) + Renderer.halfViewSize())); - } - else { - Renderer.setLineY((int) ((Renderer.getViewSize() - 20) - array[0] * Renderer.getYScale())); - } - for(int i = 0; i < Renderer.getArrayLength(); i++) { - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - if (width == 0) continue; - - int y; - if(ArrayVisualizer.waveEnabled()) { - y = (int) ((Renderer.getViewSize() / 4) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize()); - } - else { - y = (int) ((Renderer.getViewSize() - 20) - (Math.max(array[i], 1) * Renderer.getYScale())); - - // Quick patch to fix the first line being horizontal for some reason - if(i == 0) y += ((Renderer.getViewSize() - 20) - array[1] * Renderer.getYScale()) - - ((Renderer.getViewSize() - 20) - array[2] * Renderer.getYScale()); - } - - if(width > 0) { - if(i > 0) { - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - lineFancy(this.mainRender, ArrayVisualizer.currentWidth()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, Renderer.getArrayLength(), ArrayVisualizer.currentWidth()); - - drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled()); - } - else if(Highlights.containsPosition(i) && Renderer.getArrayLength() != 2) { - lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, Renderer.getArrayLength(), ArrayVisualizer.currentWidth()); - - this.mainRender.drawLine(Renderer.getOffset() + 20, Renderer.getYOffset() + y, Renderer.getLineX() + 20, Renderer.getLineY()); - } - Renderer.setLineX(Renderer.getOffset()); - Renderer.setLineY(y); - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } - else { - for(int i = 0; i < Renderer.getArrayLength(); i++) { - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - if (width == 0) continue; - - if(i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.GREEN); - } - else if(i == Highlights.getFancyFinishPosition() && Highlights.fancyFinishActive()) { - if(ArrayVisualizer.colorEnabled()) { - this.mainRender.setColor(Color.WHITE); - } - else this.mainRender.setColor(Color.RED); - } - else if(ArrayVisualizer.colorEnabled()) { - this.mainRender.setColor(getIntColor(array[i], Renderer.getArrayLength())); - } - else this.mainRender.setColor(Color.WHITE); - - int y = 0; - - boolean drawRect = false; - if(Highlights.containsPosition(i) && Renderer.getArrayLength() != 2) { - setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - drawRect = true; - } - - if(width > 0) { - if(ArrayVisualizer.waveEnabled()) { - y = (int) ((Renderer.getViewSize() / 4) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize()); - } - else { - y = (int) ((Renderer.getViewSize() - 20) - (array[i] * Renderer.getYScale())); - } - this.mainRender.fillRect(Renderer.getOffset() + 20, Renderer.getYOffset() + y, Renderer.getDotDimensions(), Renderer.getDotDimensions()); - - if(drawRect) { - this.extraRender.setStroke(ArrayVisualizer.getThickStroke()); - - if(Highlights.fancyFinishActive()) { - this.extraRender.fillRect(Renderer.getOffset() + 10, Renderer.getYOffset() + y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20); - } - else { - this.extraRender.drawRect(Renderer.getOffset() + 10, Renderer.getYOffset() + y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20); - } - - this.extraRender.setStroke(new BasicStroke(3f * (ArrayVisualizer.currentWidth() / 1280f))); //TODO: This BasicStroke should have a getDefaultStroke() method - } - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } - if (ArrayVisualizer.externalArraysEnabled() && !ArrayVisualizer.rainbowEnabled()) { - this.mainRender.setColor(Color.BLUE); - this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); - } - } -} \ No newline at end of file diff --git a/src/visuals/VisualStyles.java b/src/visuals/VisualStyles.java index b028633e..21b4cd38 100644 --- a/src/visuals/VisualStyles.java +++ b/src/visuals/VisualStyles.java @@ -37,35 +37,89 @@ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Re ArrayVisualizer.getVisuals()[0].drawVisual(array, ArrayVisualizer, Renderer, Highlights); } }, - CIRCULAR { + RAINBOW { @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { ArrayVisualizer.getVisuals()[1].drawVisual(array, ArrayVisualizer, Renderer, Highlights); } }, - CUSTOMIMAGE { + DISP_BARS { @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { ArrayVisualizer.getVisuals()[2].drawVisual(array, ArrayVisualizer, Renderer, Highlights); } }, - MESH { + COLOR_CIRCLE { @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { ArrayVisualizer.getVisuals()[3].drawVisual(array, ArrayVisualizer, Renderer, Highlights); } }, - PIXELS { + DISP_CIRCLE { @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { ArrayVisualizer.getVisuals()[4].drawVisual(array, ArrayVisualizer, Renderer, Highlights); } }, - HOOPSTACK { + DISP_CHORDS { @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { ArrayVisualizer.getVisuals()[5].drawVisual(array, ArrayVisualizer, Renderer, Highlights); } + }, + DISP_DOTS { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[6].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + DOTS { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[7].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + WAVE_DOTS { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[8].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + CUSTOM_IMAGE { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[9].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + SINE_WAVE { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[10].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + HOOP_STACK { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[11].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + PIXEL_MESH { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[12].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + SPIRAL { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[13].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } + }, + SPIRAL_DOTS { + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + ArrayVisualizer.getVisuals()[14].drawVisual(array, ArrayVisualizer, Renderer, Highlights); + } }; public VisualStyles getCurrentVisual() { diff --git a/src/visuals/bars/BarGraph.java b/src/visuals/bars/BarGraph.java new file mode 100644 index 00000000..bc5ac2c3 --- /dev/null +++ b/src/visuals/bars/BarGraph.java @@ -0,0 +1,51 @@ +package visuals.bars; + +import java.awt.Color; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +final public class BarGraph extends Visual { + + public BarGraph(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + if(width > 0) { + int y = (int) (((Renderer.getViewSize() - 20)) - (array[i] + 1) * Renderer.getYScale()); + this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, width, (int) ((array[i] + 1) * Renderer.getYScale())); + } + j += width; + } + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + if(Highlights.containsPosition(i)) { + int y = (int) (((Renderer.getViewSize() - 20)) - (array[i] + 1) * Renderer.getYScale()); + this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, Math.max(width, 2), (int) ((array[i] + 1) * Renderer.getYScale())); + } + j += width; + } + if(ArrayVisualizer.externalArraysEnabled()) { + this.mainRender.setColor(Color.BLUE); + this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); + } + } +} \ No newline at end of file diff --git a/src/visuals/bars/ColorfulBarGraph.java b/src/visuals/bars/ColorfulBarGraph.java deleted file mode 100644 index 255c874f..00000000 --- a/src/visuals/bars/ColorfulBarGraph.java +++ /dev/null @@ -1,70 +0,0 @@ -package visuals.bars; - -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; -import visuals.Visual; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class ColorfulBarGraph extends Visual { - public ColorfulBarGraph(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){ - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.GREEN); - } - else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - - drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled()); - } - else { - this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - - if(ArrayVisualizer.getCurrentLength() != 2) { - colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled()); - } - } - - int y = 0; - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - - if(width > 0) { - y = (int) (((ArrayVisualizer.windowHeight() - 20)) - (array[i] + 1) * Renderer.getYScale()); - mainRender.fillRect(Renderer.getOffset() + 20, y, width, (int) ((array[i] + 1) * Renderer.getYScale())); - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } -} \ No newline at end of file diff --git a/src/visuals/bars/DisparityBarGraph.java b/src/visuals/bars/DisparityBarGraph.java new file mode 100644 index 00000000..81fc1e52 --- /dev/null +++ b/src/visuals/bars/DisparityBarGraph.java @@ -0,0 +1,55 @@ +package visuals.bars; + +import java.awt.Color; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +final public class DisparityBarGraph extends Visual { + + public DisparityBarGraph(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + if(width > 0) { + double disp = (1 + Math.cos((Math.PI * (array[i] - i)) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + int y = (int) (((Renderer.getViewSize() - 20)) - disp * (array[i] + 1) * Renderer.getYScale()); + + this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, width, (int) (disp * (array[i] + 1) * Renderer.getYScale())); + } + j += width; + } + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + if(Highlights.containsPosition(i)) { + double disp = (1 + Math.cos((Math.PI * (array[i] - i)) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + int y = (int) (((Renderer.getViewSize() - 20)) - disp * (array[i] + 1) * Renderer.getYScale()); + + this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, Math.max(width, 2), (int) (disp * (array[i] + 1) * Renderer.getYScale())); + } + j += width; + } + if(ArrayVisualizer.externalArraysEnabled()) { + this.mainRender.setColor(Color.BLUE); + this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); + } + } +} \ No newline at end of file diff --git a/src/visuals/bars/RainbowBars.java b/src/visuals/bars/Rainbow.java similarity index 51% rename from src/visuals/bars/RainbowBars.java rename to src/visuals/bars/Rainbow.java index 42a0923a..cd48890d 100644 --- a/src/visuals/bars/RainbowBars.java +++ b/src/visuals/bars/Rainbow.java @@ -33,37 +33,40 @@ of this software and associated documentation files (the "Software"), to deal * */ -final public class RainbowBars extends Visual { - public RainbowBars(ArrayVisualizer ArrayVisualizer) { +final public class Rainbow extends Visual { + public Rainbow(ArrayVisualizer ArrayVisualizer) { super(ArrayVisualizer); } @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){ - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.GREEN); - } - else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - - drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled()); - } - else { - this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - - if(ArrayVisualizer.getCurrentLength() != 2) { - colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled()); - } - } - - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - - if(width > 0) { - this.mainRender.fillRect(Renderer.getOffset() + 20, 0, width, ArrayVisualizer.windowHeight()); - } - - Renderer.setOffset(Renderer.getOffset() + width); + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + if(width > 0) this.mainRender.fillRect(j + 20, Renderer.getYOffset() - 20, width, (int) (Renderer.getViewSize())); + + j += width; } + if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.LIGHT_GRAY); + else this.mainRender.setColor(Color.WHITE); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + if(Highlights.containsPosition(i)) { + + this.mainRender.fillRect(j + 20, Renderer.getYOffset() - 20, Math.max(width, 2), (int) (Renderer.getViewSize())); + } + j += width; + } + if(ArrayVisualizer.externalArraysEnabled()) { + this.mainRender.setColor(Color.BLUE); + this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); + } } } \ No newline at end of file diff --git a/src/visuals/bars/SineWave.java b/src/visuals/bars/SineWave.java new file mode 100644 index 00000000..6403a8a9 --- /dev/null +++ b/src/visuals/bars/SineWave.java @@ -0,0 +1,77 @@ +package visuals.bars; + +import java.awt.Color; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2020 MusicTheorist +Copyright (c) 2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class SineWave extends Visual { + + public SineWave(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + int y = (int) (((Renderer.getViewSize() - 20) / 2.5) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize() - 20); + this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, Math.max(width, 1), 20); + + j += width; + } + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + + if(Highlights.containsPosition(i)) { + int y = (int) (((Renderer.getViewSize() - 20) / 2.5) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize() - 20); + this.mainRender.fillRect(j + 20, Renderer.getYOffset() + y, Math.max(width, 2), 20); + } + j += width; + } + if(ArrayVisualizer.externalArraysEnabled()) { + this.mainRender.setColor(Color.BLUE); + this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); + } + } +} \ No newline at end of file diff --git a/src/visuals/bars/WhiteBarGraph.java b/src/visuals/bars/WhiteBarGraph.java deleted file mode 100644 index 1919c62f..00000000 --- a/src/visuals/bars/WhiteBarGraph.java +++ /dev/null @@ -1,70 +0,0 @@ -package visuals.bars; - -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; -import visuals.Visual; - -final public class WhiteBarGraph extends Visual { - - public WhiteBarGraph(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){ - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.GREEN); - } - else this.mainRender.setColor(Color.WHITE); - - drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled()); - } - else { - this.mainRender.setColor(Color.WHITE); - - if(ArrayVisualizer.getCurrentLength() != 2) { - colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.analysisEnabled()); - } - } - /* - int markHeight = 0; - Color currentColor = mainRender.getColor(); - if(currentColor == Color.BLACK || currentColor == Color.RED || currentColor == Color.BLUE) { - markHeight = 5; - } - */ - - int y = 0; - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - - if(width > 0) { - /* - int gap = 0; - if(width > 5) { - gap = 5; - } - */ - - y = (int) (((ArrayVisualizer.windowHeight() - 20)) - (array[i] + 1) * Renderer.getYScale()); - mainRender.fillRect(Renderer.getOffset() + 20, y, width, (int) ((array[i] + 1) * Renderer.getYScale())); - - //mainRender.fillRect(Renderer.getOffset() + 20, y /*- markHeight*/, width /*- gap*/, (int) ((array[i] + 1) * Renderer.getYScale()) /*+ markHeight*/); - - /* - double thickness = 1; - Stroke oldStroke = mainRender.getStroke(); - mainRender.setStroke(new BasicStroke((float) thickness)); - mainRender.setColor(Color.BLACK); - mainRender.drawLine(Renderer.getOffset() + 20, y, Renderer.getOffset() + 20, (int) Math.max(array[i] * Renderer.getYScale()-1, 1) + y); - mainRender.setStroke(oldStroke); - */ - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } -} \ No newline at end of file diff --git a/src/visuals/circles/ColorCircle.java b/src/visuals/circles/ColorCircle.java index df774ccc..3b884bd2 100644 --- a/src/visuals/circles/ColorCircle.java +++ b/src/visuals/circles/ColorCircle.java @@ -14,6 +14,7 @@ MIT License Copyright (c) 2019 w0rthy +Copyright (c) 2021 ArrayV 4.0 Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -36,109 +37,65 @@ of this software and associated documentation files (the "Software"), to deal */ final public class ColorCircle extends Visual { - final private static double CIRC_HEIGHT_RATIO = (9/6.0843731432) * (16/9d); - final private static double CIRC_WIDTH_RATIO = (16/6.0843731432) * (16/9d); - + public ColorCircle(ArrayVisualizer ArrayVisualizer) { super(ArrayVisualizer); } - // The reason we use cosine with height (expressed in terms of y) and sine with width (expressed in terms of x) is because our circles are rotated 90 degrees. - // After that rotation, sine is on the x-axis and cosine is on the y-axis. - - // If we we use sine with height and cosine with width, the sorts would start from the right side of the circle, - // just like the unit circle from trigonometry. - - private static double getSinOfDegrees(double d, int halfCirc) { - return Math.sin((d * Math.PI) / halfCirc); - } - - private static double getCosOfDegrees(double d, int halfCirc) { - return Math.cos((d * Math.PI) / halfCirc); - } - @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){ - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.getHSBColor((1f/3f), 1f, 0.8f)); - } - else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - - drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled()); - } - if(Highlights.fancyFinishActive()) { - drawFancyFinish(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled()); - } - else { - this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - colorMarkedBars(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights, this.mainRender, ArrayVisualizer.rainbowEnabled(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - - /* - if(ArrayVisualizer.pointerActive()) { - if(Highlights.containsPosition(i)) { - if(ArrayVisualizer.analysisEnabled()) { - this.extraRender.setColor(Color.GRAY); - } - else { - this.extraRender.setColor(Color.WHITE); - } - - //Create new Polygon for the pointer - Polygon pointer = new Polygon(); - - //Calculate radians - double degrees = 360 * ((double) i / ArrayVisualizer.getCurrentLength()); - double radians = Math.toRadians(degrees); - - int pointerWidthRatio = (int) (ArrayVisualizer.windowHalfWidth() / CIRC_WIDTH_RATIO); - int pointerHeightRatio = (int) (ArrayVisualizer.windowHalfHeight() / CIRC_HEIGHT_RATIO); - - //First step: draw a triangle - int[] pointerXValues = {pointerWidthRatio - 10, - pointerWidthRatio, - pointerWidthRatio + 10}; - - int[] pointerYValues = {pointerHeightRatio - 10, - pointerHeightRatio + 10, - pointerHeightRatio - 10}; - - //Second step: rotate triangle (https://en.wikipedia.org/wiki/Rotation_matrix) - for(int j = 0; j < pointerXValues.length; j++) { - double x = pointerXValues[j] - pointerWidthRatio; - double y = pointerYValues[j] - pointerHeightRatio; - - pointerXValues[j] = (int) (pointerWidthRatio - + x*Math.cos(radians) - - y*Math.sin(radians)); - pointerYValues[j] = (int) (pointerHeightRatio - + x*Math.sin(radians) - + y*Math.cos(radians)); - } - - for(int j = 0; j < pointerXValues.length; j++) { - pointer.addPoint(pointerXValues[j], pointerYValues[j]); - } - - this.extraRender.fillPolygon(pointer); - } - } - else */ - } - - Polygon p = new Polygon(); - - p.addPoint(ArrayVisualizer.windowHalfWidth(), - ArrayVisualizer.windowHalfHeight()); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (ColorCircle.getSinOfDegrees(i, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowWidth() - 64) / CIRC_WIDTH_RATIO)), - ArrayVisualizer.windowHalfHeight() - (int) (ColorCircle.getCosOfDegrees(i, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowHeight() - 96) / CIRC_HEIGHT_RATIO))); - - p.addPoint(ArrayVisualizer.windowHalfWidth() + (int) (ColorCircle.getSinOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowWidth() - 64) / CIRC_WIDTH_RATIO)), - ArrayVisualizer.windowHalfHeight() - (int) (ColorCircle.getCosOfDegrees(i + 1, ArrayVisualizer.halfCircle()) * ((ArrayVisualizer.windowHeight() - 96) / CIRC_HEIGHT_RATIO))); - - this.mainRender.fillPolygon(p); - } + if(Renderer.auxActive) return; + + int width = ArrayVisualizer.windowWidth(); + int height = ArrayVisualizer.windowHeight(); + + int n = ArrayVisualizer.getCurrentLength(); + + double r = Math.min(width, height)/2.75; + int p = (int)(r/16); + + int[] x = new int[3]; + int[] y = new int[3]; + + int[] px = new int[3]; + int[] py = new int[3]; + + this.extraRender.setColor(Color.WHITE); + + x[0] = width/2; + y[0] = height/2; + + x[2] = width/2 + (int)(r * Math.cos(Math.PI * (2d*(n-1) / n - 0.5))); + y[2] = height/2 + (int)(r * Math.sin(Math.PI * (2d*(n-1) / n - 0.5))); + + for(int i = 0; i < n; i++) { + x[1] = x[2]; + y[1] = y[2]; + + x[2] = width/2 + (int)(r * Math.cos(Math.PI * (2d*i / n - 0.5))); + y[2] = height/2 + (int)(r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(Highlights.containsPosition(i)) { + if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.LIGHT_GRAY); + else this.mainRender.setColor(Color.WHITE); + + px[0] = width/2 + (int)((r + p/4) * Math.cos(Math.PI * ((2d*i - 1) / n - 0.5))); + py[0] = height/2 + (int)((r + p/4) * Math.sin(Math.PI * ((2d*i - 1) / n - 0.5))); + + px[1] = px[0] + (int)(p * Math.cos(Math.PI * ((2d*i - 1) / n - 0.67))); + py[1] = py[0] + (int)(p * Math.sin(Math.PI * ((2d*i - 1) / n - 0.67))); + + px[2] = px[0] + (int)(p * Math.cos(Math.PI * ((2d*i - 1) / n - 0.33))); + py[2] = py[0] + (int)(p * Math.sin(Math.PI * ((2d*i - 1) / n - 0.33))); + + this.extraRender.fillPolygon(px, py, 3); + } + else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + if(x[1] != x[2] || y[1] != y[2]) this.mainRender.fillPolygon(x, y, 3); + } } } \ No newline at end of file diff --git a/src/visuals/circles/DisparityChords.java b/src/visuals/circles/DisparityChords.java new file mode 100644 index 00000000..11efefb8 --- /dev/null +++ b/src/visuals/circles/DisparityChords.java @@ -0,0 +1,93 @@ +package visuals.circles; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Polygon; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy +Copyright (c) 2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class DisparityChords extends Visual { + + public DisparityChords(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + if(Renderer.auxActive) return; + + int width = ArrayVisualizer.windowWidth(); + int height = ArrayVisualizer.windowHeight(); + + int n = ArrayVisualizer.getCurrentLength(); + double r = Math.min(width, height)/2.5; + + this.mainRender.setStroke(ArrayVisualizer.getThinStroke()); + + for(int i = n-1; i >= 0; i--) { + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + int ax = width/2 + (int)(r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int ay = height/2 + (int)(r * Math.sin(Math.PI * (2d*i / n - 0.5))); + int bx = width/2 + (int)(r * Math.cos(Math.PI * (2d*array[i] / n - 0.5))); + int by = height/2 + (int)(r * Math.sin(Math.PI * (2d*array[i] / n - 0.5))); + + this.mainRender.drawLine(ax, ay, bx, by); + } + this.mainRender.setStroke(ArrayVisualizer.getDefaultStroke()); + + for(int i = 0; i < n; i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { + this.mainRender.setColor(Color.GREEN); + + int ax = width/2 + (int)(r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int ay = height/2 + (int)(r * Math.sin(Math.PI * (2d*i / n - 0.5))); + int bx = width/2 + (int)(r * Math.cos(Math.PI * (2d*array[i] / n - 0.5))); + int by = height/2 + (int)(r * Math.sin(Math.PI * (2d*array[i] / n - 0.5))); + + this.mainRender.drawLine(ax, ay, bx, by); + } + else if(Highlights.containsPosition(i)) { + if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.LIGHT_GRAY); + else this.mainRender.setColor(Color.WHITE); + + int ax = width/2 + (int)(r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int ay = height/2 + (int)(r * Math.sin(Math.PI * (2d*i / n - 0.5))); + int bx = width/2 + (int)(r * Math.cos(Math.PI * (2d*array[i] / n - 0.5))); + int by = height/2 + (int)(r * Math.sin(Math.PI * (2d*array[i] / n - 0.5))); + + this.mainRender.drawLine(ax, ay, bx, by); + } + } + } +} \ No newline at end of file diff --git a/src/visuals/circles/DisparityCircle.java b/src/visuals/circles/DisparityCircle.java new file mode 100644 index 00000000..5dbcdcef --- /dev/null +++ b/src/visuals/circles/DisparityCircle.java @@ -0,0 +1,89 @@ +package visuals.circles; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Polygon; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy +Copyright (c) 2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class DisparityCircle extends Visual { + + public DisparityCircle(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + if(Renderer.auxActive) return; + + int width = ArrayVisualizer.windowWidth(); + int height = ArrayVisualizer.windowHeight(); + + int n = ArrayVisualizer.getCurrentLength(); + double r = Math.min(width, height)/2.5; + + this.extraRender.setStroke(ArrayVisualizer.getThickStroke()); + this.extraRender.setColor(ArrayVisualizer.getHighlightColor()); + + int[] x = {width/2, 0, 0}; + int[] y = {height/2, 0, 0}; + + double disp = (1 + Math.cos((Math.PI * (array[n-1] - (n-1))) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + x[2] = width/2 + (int)(disp * r * Math.cos(Math.PI * (2d*(n-1) / n - 0.5))); + y[2] = height/2 + (int)(disp * r * Math.sin(Math.PI * (2d*(n-1) / n - 0.5))); + + for(int i = 0; i < n; i++) { + x[1] = x[2]; + y[1] = y[2]; + + disp = (1 + Math.cos((Math.PI * (array[i] - i)) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + x[2] = width/2 + (int)(disp * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + y[2] = height/2 + (int)(disp * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(Highlights.containsPosition(i)) { + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + this.extraRender.drawPolygon(x, y, 3); + } + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + this.mainRender.fillPolygon(x, y, 3); + } + this.extraRender.setStroke(ArrayVisualizer.getDefaultStroke()); + } +} \ No newline at end of file diff --git a/src/visuals/circles/Spiral.java b/src/visuals/circles/Spiral.java new file mode 100644 index 00000000..a2535abf --- /dev/null +++ b/src/visuals/circles/Spiral.java @@ -0,0 +1,89 @@ +package visuals.circles; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Polygon; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy +Copyright (c) 2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class Spiral extends Visual { + + public Spiral(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + if(Renderer.auxActive) return; + + int width = ArrayVisualizer.windowWidth(); + int height = ArrayVisualizer.windowHeight(); + + int n = ArrayVisualizer.getCurrentLength(); + double r = Math.min(width, height)/2.5; + + this.extraRender.setStroke(ArrayVisualizer.getThickStroke()); + this.extraRender.setColor(ArrayVisualizer.getHighlightColor()); + + int[] x = {width/2, 0, 0}; + int[] y = {height/2, 0, 0}; + + double mult = (double) array[n-1] / ArrayVisualizer.getCurrentLength(); + x[2] = width/2 + (int)(mult * r * Math.cos(Math.PI * (2d*(n-1) / n - 0.5))); + y[2] = height/2 + (int)(mult * r * Math.sin(Math.PI * (2d*(n-1) / n - 0.5))); + + for(int i = 0; i < n; i++) { + x[1] = x[2]; + y[1] = y[2]; + + mult = (double) array[i] / ArrayVisualizer.getCurrentLength(); + x[2] = width/2 + (int)(mult * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + y[2] = height/2 + (int)(mult * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(Highlights.containsPosition(i)) { + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + this.extraRender.drawPolygon(x, y, 3); + } + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + this.mainRender.fillPolygon(x, y, 3); + } + this.extraRender.setStroke(ArrayVisualizer.getDefaultStroke()); + } +} \ No newline at end of file diff --git a/src/visuals/dots/ColorfulScatterPlot.java b/src/visuals/dots/ColorfulScatterPlot.java deleted file mode 100644 index 399b1959..00000000 --- a/src/visuals/dots/ColorfulScatterPlot.java +++ /dev/null @@ -1,78 +0,0 @@ -package visuals.dots; - -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; -import visuals.Visual; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class ColorfulScatterPlot extends Visual { - public ColorfulScatterPlot(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) { - if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.GREEN); - } - else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - - int y = 0; - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - - boolean drawRect = false; - if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) { - setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - drawRect = true; - } - - if(width > 0) { - y = (int) ((ArrayVisualizer.windowHeight() - 20) - (array[i] * Renderer.getYScale())); - this.mainRender.fillRect(Renderer.getOffset() + 20, y, Renderer.getDotDimensions(), Renderer.getDotDimensions()); - - if(drawRect) { - this.extraRender.setStroke(ArrayVisualizer.getThickStroke()); - - if(Highlights.fancyFinishActive()) { - this.extraRender.fillRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20); - } - else { - this.extraRender.drawRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20); - } - - this.extraRender.setStroke(ArrayVisualizer.getDefaultStroke()); - } - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } -} \ No newline at end of file diff --git a/src/visuals/dots/DisparityDots.java b/src/visuals/dots/DisparityDots.java new file mode 100644 index 00000000..b1ba916a --- /dev/null +++ b/src/visuals/dots/DisparityDots.java @@ -0,0 +1,118 @@ +package visuals.dots; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Polygon; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy +Copyright (c) 2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class DisparityDots extends Visual { + + public DisparityDots(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + if(Renderer.auxActive) return; + + int width = ArrayVisualizer.windowWidth(); + int height = ArrayVisualizer.windowHeight(); + + int n = ArrayVisualizer.getCurrentLength(); + double r = Math.min(width, height)/2.5; + + if(ArrayVisualizer.linesEnabled()) { + double disp = (1 + Math.cos((Math.PI * (array[n-1] - (n-1))) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + int lastX = width/2 + (int)(disp * r * Math.cos(Math.PI * (2d*(n-1) / n - 0.5))); + int lastY = height/2 + (int)(disp * r * Math.sin(Math.PI * (2d*(n-1) / n - 0.5))); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + for(int i = 0; i < n; i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { + this.mainRender.setColor(Color.GREEN); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(4)); + } + else if(Highlights.containsPosition(i)) { + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(4)); + } + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + disp = (1 + Math.cos((Math.PI * (array[i] - i)) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + int x = width/2 + (int)(disp * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int y = height/2 + (int)(disp * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + this.mainRender.drawLine(lastX, lastY, x, y); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + lastX = x; + lastY = y; + } + this.mainRender.setStroke(ArrayVisualizer.getDefaultStroke()); + } + else { + int dotS = Renderer.getDotDimensions(); + + for(int i = 0; i < n; i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + double disp = (1 + Math.cos((Math.PI * (array[i] - i)) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + int x = width/2 + (int)(disp * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int y = height/2 + (int)(disp * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + this.mainRender.fillRect(x, y, dotS, dotS); + } + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + + for(int i = 0; i < n; i++) { + if(Highlights.containsPosition(i)) { + double disp = (1 + Math.cos((Math.PI * (array[i] - i)) / (ArrayVisualizer.getCurrentLength() * 0.5))) * 0.5; + int x = width/2 + (int)(disp * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int y = height/2 + (int)(disp * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + this.mainRender.fillRect(x - 2*dotS, y - 2*dotS, 4*dotS, 4*dotS); + } + } + } + } +} \ No newline at end of file diff --git a/src/visuals/dots/ScatterPlot.java b/src/visuals/dots/ScatterPlot.java new file mode 100644 index 00000000..290b02ba --- /dev/null +++ b/src/visuals/dots/ScatterPlot.java @@ -0,0 +1,113 @@ +package visuals.dots; + +import java.awt.Color; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class ScatterPlot extends Visual { + public ScatterPlot(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + int offset = 20 + (int) (Renderer.getXScale()/2); + + if(ArrayVisualizer.linesEnabled()) { + int lastX = 0; + int lastY = (int) (((Renderer.getViewSize() - 20)) - (array[0] + 1) * Renderer.getYScale()); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + for(int i = 1, j = (int) Renderer.getXScale(); i < Renderer.getArrayLength(); i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { + this.mainRender.setColor(Color.GREEN); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(4)); + } + else if(Highlights.containsPosition(i)) { + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(4)); + } + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i-1], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + int y = (int) (((Renderer.getViewSize() - 20)) - (array[i] + 1) * Renderer.getYScale()); + + this.mainRender.drawLine(lastX + offset, Renderer.getYOffset() + lastY, j + offset, Renderer.getYOffset() + y); + + lastX = j; + lastY = y; + + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + j += width; + } + this.mainRender.setStroke(ArrayVisualizer.getDefaultStroke()); + } + else { + int dotS = Renderer.getDotDimensions(); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + int y = (int) (((Renderer.getViewSize() - 20)) - (array[i] + 1) * Renderer.getYScale()); + + this.mainRender.fillRect(j + offset, Renderer.getYOffset() + y, dotS, dotS); + + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + j += width; + } + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + if(Highlights.containsPosition(i)) { + int y = (int) (((Renderer.getViewSize() - 20)) - (array[i] + 1) * Renderer.getYScale()); + this.mainRender.fillRect(j + offset - (int)(1.5*dotS), Renderer.getYOffset() + y - (int)(1.5*dotS), 4*dotS, 4*dotS); + } + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + j += width; + } + } + if(ArrayVisualizer.externalArraysEnabled()) { + this.mainRender.setColor(Color.BLUE); + this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); + } + } +} \ No newline at end of file diff --git a/src/visuals/dots/SpiralDots.java b/src/visuals/dots/SpiralDots.java new file mode 100644 index 00000000..11ff067f --- /dev/null +++ b/src/visuals/dots/SpiralDots.java @@ -0,0 +1,117 @@ +package visuals.dots; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Polygon; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy +Copyright (c) 2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class SpiralDots extends Visual { + + public SpiralDots(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + if(Renderer.auxActive) return; + + int width = ArrayVisualizer.windowWidth(); + int height = ArrayVisualizer.windowHeight(); + + int n = ArrayVisualizer.getCurrentLength(); + double r = Math.min(width, height)/2.5; + + if(ArrayVisualizer.linesEnabled()) { + double mult = (double) array[n-1] / ArrayVisualizer.getCurrentLength(); + int lastX = width/2 + (int)(mult * r * Math.cos(Math.PI * (2d*(n-1) / n - 0.5))); + int lastY = height/2 + (int)(mult * r * Math.sin(Math.PI * (2d*(n-1) / n - 0.5))); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + for(int i = 0; i < n; i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + if(Highlights.containsPosition(i)) { + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(4)); + } + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + mult = (double) array[i] / ArrayVisualizer.getCurrentLength(); + int x = width/2 + (int)(mult * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int y = height/2 + (int)(mult * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + this.mainRender.drawLine(lastX, lastY, x, y); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + lastX = x; + lastY = y; + } + this.mainRender.setStroke(ArrayVisualizer.getDefaultStroke()); + } + else { + int dotS = Renderer.getDotDimensions(); + + for(int i = 0; i < n; i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + double mult = (double) array[i] / ArrayVisualizer.getCurrentLength(); + int x = width/2 + (int)(mult * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int y = height/2 + (int)(mult * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + this.mainRender.fillRect(x, y, dotS, dotS); + } + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + + for(int i = 0; i < n; i++) { + if(Highlights.containsPosition(i)) { + double mult = (double) array[i] / ArrayVisualizer.getCurrentLength(); + int x = width/2 + (int)(mult * r * Math.cos(Math.PI * (2d*i / n - 0.5))); + int y = height/2 + (int)(mult * r * Math.sin(Math.PI * (2d*i / n - 0.5))); + + this.mainRender.fillRect(x - 2*dotS, y - 2*dotS, 4*dotS, 4*dotS); + } + } + } + } +} \ No newline at end of file diff --git a/src/visuals/dots/WaveDots.java b/src/visuals/dots/WaveDots.java new file mode 100644 index 00000000..0fd8a4b6 --- /dev/null +++ b/src/visuals/dots/WaveDots.java @@ -0,0 +1,115 @@ +package visuals.dots; + +import java.awt.Color; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy +Copyright (c) 2020 MusicTheorist +Copyright (c) 2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class WaveDots extends Visual { + public WaveDots(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + int offset = 20 + (int) (Renderer.getXScale()/2); + + if(ArrayVisualizer.linesEnabled()) { + int lastX = 0; + int lastY = (int) (((Renderer.getViewSize() - 20) / 2.5) * Math.sin((2 * Math.PI * ((double) array[0] / Renderer.getArrayLength()))) + Renderer.halfViewSize() - 20); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + for(int i = 1, j = (int) Renderer.getXScale(); i < Renderer.getArrayLength(); i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { + this.mainRender.setColor(Color.GREEN); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(4)); + } + else if(Highlights.containsPosition(i)) { + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(4)); + } + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i-1], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + int y = (int) (((Renderer.getViewSize() - 20) / 2.5) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize() - 20); + + this.mainRender.drawLine(lastX + offset, Renderer.getYOffset() + lastY, j + offset, Renderer.getYOffset() + y); + + lastX = j; + lastY = y; + + this.mainRender.setStroke(ArrayVisualizer.getCustomStroke(2)); + + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + j += width; + } + this.mainRender.setStroke(ArrayVisualizer.getDefaultStroke()); + } + else { + int dotS = Renderer.getDotDimensions(); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(ArrayVisualizer.colorEnabled()) + this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); + + else this.mainRender.setColor(Color.WHITE); + + int y = (int) (((Renderer.getViewSize() - 20) / 2.5) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize() - 20); + + this.mainRender.fillRect(j + offset, Renderer.getYOffset() + y, dotS, dotS); + + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + j += width; + } + this.mainRender.setColor(ArrayVisualizer.getHighlightColor()); + + for(int i = 0, j = 0; i < Renderer.getArrayLength(); i++) { + if(Highlights.containsPosition(i)) { + int y = (int) (((Renderer.getViewSize() - 20) / 2.5) * Math.sin((2 * Math.PI * ((double) array[i] / Renderer.getArrayLength()))) + Renderer.halfViewSize() - 20); + this.mainRender.fillRect(j + offset - (int)(1.5*dotS), Renderer.getYOffset() + y - (int)(1.5*dotS), 4*dotS, 4*dotS); + } + int width = (int) (Renderer.getXScale() * (i + 1)) - j; + j += width; + } + } + if(ArrayVisualizer.externalArraysEnabled()) { + this.mainRender.setColor(Color.BLUE); + this.mainRender.fillRect(0, Renderer.getYOffset() + Renderer.getViewSize() - 20, ArrayVisualizer.currentWidth(), 1); + } + } +} \ No newline at end of file diff --git a/src/visuals/dots/WhiteScatterPlot.java b/src/visuals/dots/WhiteScatterPlot.java deleted file mode 100644 index 52923f84..00000000 --- a/src/visuals/dots/WhiteScatterPlot.java +++ /dev/null @@ -1,78 +0,0 @@ -package visuals.dots; - -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; -import visuals.Visual; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class WhiteScatterPlot extends Visual { - public WhiteScatterPlot(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) { - if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { - this.mainRender.setColor(Color.GREEN); - } - else this.mainRender.setColor(Color.WHITE); - - int y = 0; - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - - boolean drawRect = false; - if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) { - setRectColor(this.extraRender, ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - drawRect = true; - } - - if(width > 0) { - y = (int) ((ArrayVisualizer.windowHeight() - 20) - (array[i] * Renderer.getYScale())); - this.mainRender.fillRect(Renderer.getOffset() + 20, y, Renderer.getDotDimensions(), Renderer.getDotDimensions()); - - if(drawRect) { - this.extraRender.setStroke(ArrayVisualizer.getThickStroke()); - - if(Highlights.fancyFinishActive()) { - this.extraRender.fillRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20); - } - else { - this.extraRender.drawRect(Renderer.getOffset() + 10, y - 10, Renderer.getDotDimensions() + 20, Renderer.getDotDimensions() + 20); - } - - this.extraRender.setStroke(ArrayVisualizer.getDefaultStroke()); - } - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } -} \ No newline at end of file diff --git a/src/visuals/image/CustomImage.java b/src/visuals/image/CustomImage.java index bc3f20f0..27983dbc 100644 --- a/src/visuals/image/CustomImage.java +++ b/src/visuals/image/CustomImage.java @@ -1,24 +1,27 @@ package visuals.image; import java.awt.Color; -import java.awt.Dialog.ModalityType; +import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; +import java.io.BufferedInputStream; +import java.io.File; import java.io.IOException; -import java.io.InputStream; import javax.imageio.ImageIO; -import javax.swing.JDialog; import javax.swing.JFrame; -import javax.swing.JOptionPane; +import visuals.Visual; +import dialogs.CustomImageDialog; +import dialogs.LoadingDialog; +import dialogs.SoundbankDialog; +import frames.ImageFrame; import main.ArrayVisualizer; import panes.JErrorPane; import resources.image.ImgFetcher; import utils.Highlights; import utils.Renderer; -import visuals.Visual; /* * @@ -52,27 +55,55 @@ of this software and associated documentation files (the "Software"), to deal * aphitorite (https://github.com/aphitorite/ArrayVisualizer) */ final public class CustomImage extends Visual { - private BufferedImage img; - private int imgHeight; - private int imgWidth; + public static CustomImage visual; + + private volatile BufferedImage img; + private volatile int imgHeight; + private volatile int imgWidth; private boolean imgImported; private boolean imgScaled; + private boolean openImgMenu; private int windowHeight; private int windowWidth; - private JOptionPane info; - private JDialog infoMsg; + private volatile ImageFrame pictureMenu; + private volatile LoadingDialog infoMsg; + + final private String defaultArtwork = "Summer Sorting by aphitorite"; + private String currentImage; + private File imageFile; public CustomImage(ArrayVisualizer ArrayVisualizer) { super(ArrayVisualizer); + CustomImage.visual = this; this.imgImported = false; // Don't load the image unless the user selects the // 'Custom Image' visual. Program initially boots up // faster this way. + this.enableImgMenu(); this.updateWindowDims(ArrayVisualizer); + this.currentImage = this.defaultArtwork; } + public BufferedImage getImage() { + return this.img; + } + public int getImgHeight() { + return this.imgHeight; + } + public int getImgWidth() { + return this.imgWidth; + } + + public String getCurrentImageName() { + return this.currentImage; + } + + public void enableImgMenu() { + this.openImgMenu = true; + } + private void updateImageDims() throws Exception { this.imgHeight = this.img.getHeight(); this.imgWidth = this.img.getWidth(); @@ -83,24 +114,61 @@ private void updateWindowDims(ArrayVisualizer ArrayVisualizer) { this.windowWidth = ArrayVisualizer.windowWidth(); } + private void refreshCustomImage(ImageFrame menu) { + menu.dispose(); + this.imgImported = false; + this.imgScaled = false; + this.openImgMenu = true; + } + + public void loadDefaultArtwork(ImageFrame menu) { + this.currentImage = this.defaultArtwork; + this.refreshCustomImage(menu); + } + public void loadCustomImage(ImageFrame menu) { + CustomImageDialog dialog = new CustomImageDialog(); + this.imageFile = dialog.getFile(); + if(this.imageFile != null) { + this.currentImage = this.imageFile.getName(); + this.refreshCustomImage(menu); + } + } + public void loadCustomImage(File file) { + this.imageFile = file; + if(this.imageFile != null) { + this.currentImage = this.imageFile.getName(); + this.refreshCustomImage(ImageFrame.defaultFrame); + } + } + @SuppressWarnings("unused") private boolean fetchBufferedImage(boolean showInfoMsg, JFrame window) { - // New copy of pic.jpg being imported; has not been scaled yet + // New copy of image being imported; has not been scaled yet this.imgScaled = false; + boolean defaultImage = this.currentImage.equals(this.defaultArtwork); + if(showInfoMsg) { - this.info = new JOptionPane("Loading image/pic.jpg...", JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[] {}, null); - this.infoMsg = this.info.createDialog(window, "Info"); - this.infoMsg.setModalityType(ModalityType.MODELESS); - this.infoMsg.setAlwaysOnTop(this.infoMsg.isAlwaysOnTopSupported()); - this.infoMsg.pack(); - this.infoMsg.setVisible(true); + String message; + if(defaultImage) { + message = "resources/image/pic.jpg"; + } + else { + message = this.currentImage; + } + this.infoMsg = new LoadingDialog(message, window); } boolean success = true; - ImgFetcher imgFetcher = new ImgFetcher(); - InputStream stream = imgFetcher.getStream(); + ImgFetcher imgFetcher; + if(defaultImage) { + imgFetcher = new ImgFetcher(); + } + else { + imgFetcher = new ImgFetcher(this.imageFile); + } + BufferedInputStream stream = imgFetcher.getStream(); try { this.img = ImageIO.read(stream); @@ -111,32 +179,59 @@ private boolean fetchBufferedImage(boolean showInfoMsg, JFrame window) { } catch (IllegalArgumentException e) { success = false; - JErrorPane.invokeCustomErrorMessage("image/pic.jpg missing: Couldn't find the default image for the program's 'Custom Image' visual!"); + if(defaultImage) { + JErrorPane.invokeCustomErrorMessage("image/pic.jpg missing: Couldn't find the default image for the program's 'Custom Image' visual!"); + } + else { + JErrorPane.invokeCustomErrorMessage(this.currentImage + " missing: ArrayV couldn't find your picture at the given location!"); + } } finally { try { stream.close(); } + catch (NullPointerException e) { + success = false; // A NullPointerException means a null stream, which would have already thrown an IllegalArgumentException + } catch (Exception e) { success = false; JErrorPane.invokeErrorMessage(e); } } - // Update the image dimensions. If this fails, the file wasn't a jpg - try { - this.updateImageDims(); - } - catch (Exception e) { - success = false; - JErrorPane.invokeCustomErrorMessage("image/pic.jpg invalid or corrupt: The file for the program's 'Custom Image' visual was not recognized as a proper JPEG!"); + // Update the image dimensions. If this fails, the file wasn't a proper image + if(success) { + try { + this.updateImageDims(); + } + catch (Exception e) { + success = false; + if(defaultImage) { + JErrorPane.invokeCustomErrorMessage("image/pic.jpg invalid or corrupt: The file for the program's 'Custom Image' visual was not recognized as a valid image!"); + } + else { + JErrorPane.invokeCustomErrorMessage(this.currentImage + " invalid or corrupt: Your picture was not recognized as a valid image!"); + } + } } if(showInfoMsg) { - this.infoMsg.setVisible(false); - this.infoMsg.dispose(); + this.infoMsg.closeDialog(); + } + + if(!success) { + // If loading a custom file didn't work, then try loading the default artwork instead. + if(!defaultImage) { + this.currentImage = this.defaultArtwork; + return this.fetchBufferedImage(true, window); + } + else { + return false; + } + } + else { + return true; } - return success; } // Many thanks to Jörn Horstmann for providing fast image scaling code. @@ -180,9 +275,43 @@ private boolean getScaledImage(int width, int height) throws Exception { return success; } + public static void markCustomBar(ArrayVisualizer ArrayVisualizer, Graphics2D bar, Renderer Renderer, int width, boolean analysis) { + if(analysis) { + bar.setColor(new Color(0, 0, 1, .5f)); + } + else { + bar.setColor(new Color(1, 0, 0, .5f)); + } + bar.fillRect(Renderer.getOffset() + 20, 0, width, ArrayVisualizer.windowHeight()); + } + + @SuppressWarnings("fallthrough") + //The longer the array length, the more bars marked. Makes the visual easier to see when bars are thinner. + public static void colorCustomBars(int logOfLen, int index, Highlights Highlights, ArrayVisualizer ArrayVisualizer, Graphics2D bar, Renderer Renderer, int width, boolean analysis) { + switch(logOfLen) { + case 15: if(Highlights.containsPosition(index - 15)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 14)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 13)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 12)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 11)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + case 14: if(Highlights.containsPosition(index - 10)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 9)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 8)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + case 13: if(Highlights.containsPosition(index - 7)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 6)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 5)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + case 12: if(Highlights.containsPosition(index - 4)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + if(Highlights.containsPosition(index - 3)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + case 11: if(Highlights.containsPosition(index - 2)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + case 10: if(Highlights.containsPosition(index - 1)) { markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); break; } + default: if(Highlights.containsPosition(index)) markCustomBar(ArrayVisualizer, bar, Renderer, width, analysis); + } + } + @Override - @SuppressWarnings("unused") public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + if(Renderer.auxActive) return; + try { /* * Load the image on first use of the 'Custom Image' visual or if the program failed to read the image file previously. @@ -190,10 +319,12 @@ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Re * handling exceptions whenever the user clicks the 'Custom Image' button. */ if(!this.imgImported) { - this.imgImported = this.fetchBufferedImage(true, ArrayVisualizer.getMainWindow()); - if(!this.imgImported) { + if(!this.fetchBufferedImage(true, ArrayVisualizer.getMainWindow())) { throw new Exception(); } + else { + this.imgImported = true; + } } /* * Use a fast image scaling method if the window was resized. If an ImagingOpException is thrown, don't continue with @@ -205,40 +336,57 @@ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Re } this.updateWindowDims(ArrayVisualizer); } + + if(this.openImgMenu) { + this.pictureMenu = new ImageFrame(this); + this.pictureMenu.setVisible(true); + this.pictureMenu.updatePreview(this); + this.openImgMenu = false; + } } catch (Exception e) { + JErrorPane.invokeErrorMessage(e); ArrayVisualizer.setVisual(visuals.VisualStyles.BARS); return; } - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) { - int width = (int) (Renderer.getXScale() * (i + 1) - Renderer.getOffset()); + for(int i = 0, j = 0; i < ArrayVisualizer.getCurrentLength(); i++) { + int width = (int) (Renderer.getXScale() * (i + 1) - j); + if(width == 0) continue; + + //Cuts the image in respect to each item in the array + this.mainRender.drawImage( + this.img, + + j + 20, + 0, + j + 20 + width, + ArrayVisualizer.windowHeight(), + + (int) ((double) this.imgWidth / ArrayVisualizer.getCurrentLength() * array[i]), + 0, + (int) Math.ceil((double) this.imgWidth / ArrayVisualizer.getCurrentLength() * (array[i] + 1)), + this.imgHeight, + + null + ); + j += width; + } + for(int i = 0, j = 0; i < ArrayVisualizer.getCurrentLength(); i++) { + int width = (int) (Renderer.getXScale() * (i + 1)) - j; - if(i < Highlights.getFancyFinishPosition() || Highlights.containsPosition(i)) { - if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.WHITE); - else this.mainRender.setColor(Color.BLACK); + if(Highlights.fancyFinishActive() && i < Highlights.getFancyFinishPosition()) { + this.mainRender.setColor(new Color(0, 1, 0, .5f)); - this.mainRender.fillRect(Renderer.getOffset() + 20, 0, width, ArrayVisualizer.windowHeight()); - } else { - //Cuts the image in respect to each item in the array - this.mainRender.drawImage( - this.img, - - Renderer.getOffset() + 20, - 0, - Renderer.getOffset() + 20 + width, - ArrayVisualizer.windowHeight(), - - (int) ((double) this.imgWidth / ArrayVisualizer.getCurrentLength() * array[i]), - 0, - (int) Math.ceil((double) this.imgWidth / ArrayVisualizer.getCurrentLength() * (array[i] + 1)), - this.imgHeight, - - null - ); + if(width > 0) this.mainRender.fillRect(j + 20, 0, width, ArrayVisualizer.windowHeight()); + } + else if(Highlights.containsPosition(i)) { + if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(new Color(0, 0, 1, .5f)); + else this.mainRender.setColor(new Color(1, 0, 0, .5f)); + + this.mainRender.fillRect(j + 20, 0, Math.max(width, 2), ArrayVisualizer.windowHeight()); } - - Renderer.setOffset(Renderer.getOffset() + width); + j += width; } } } \ No newline at end of file diff --git a/src/visuals/lines/ColorfulLinePlot.java b/src/visuals/lines/ColorfulLinePlot.java deleted file mode 100644 index 8a0d5ed1..00000000 --- a/src/visuals/lines/ColorfulLinePlot.java +++ /dev/null @@ -1,72 +0,0 @@ -package visuals.lines; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; -import visuals.Visual; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class ColorfulLinePlot extends Visual { - public ColorfulLinePlot(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - Renderer.setLineY((int) ((ArrayVisualizer.windowHeight() - 20) - array[0] * Renderer.getYScale())); - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) { - int y = (int) ((ArrayVisualizer.windowHeight() - 20) - (Math.max(array[i], 1) * Renderer.getYScale())); - - // Quick patch to fix the first line being horizontal for some reason - if(i == 0) y += ((ArrayVisualizer.windowHeight() - 20) - array[1] * Renderer.getYScale()) - - ((ArrayVisualizer.windowHeight() - 20) - array[2] * Renderer.getYScale()); - - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - - if(width > 0) { - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - lineFancy(this.mainRender, ArrayVisualizer.currentWidth()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - - drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled()); - } - else if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) { - lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - - this.mainRender.drawLine(Renderer.getOffset() + 20, y, Renderer.getLineX() + 20, Renderer.getLineY()); - Renderer.setLineX(Renderer.getOffset()); - Renderer.setLineY(y); - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } -} \ No newline at end of file diff --git a/src/visuals/lines/WhiteLinePlot.java b/src/visuals/lines/WhiteLinePlot.java deleted file mode 100644 index 21b6ecf5..00000000 --- a/src/visuals/lines/WhiteLinePlot.java +++ /dev/null @@ -1,74 +0,0 @@ -package visuals.lines; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; -import visuals.Visual; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class WhiteLinePlot extends Visual { - public WhiteLinePlot(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - Renderer.setLineY((int) ((ArrayVisualizer.windowHeight() - 20) - array[0] * Renderer.getYScale())); - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++) { - int y = (int) ((ArrayVisualizer.windowHeight() - 20) - (Math.max(array[i], 1) * Renderer.getYScale())); - - // Quick patch to fix the first line being horizontal for some reason - if(i == 0) y += ((ArrayVisualizer.windowHeight() - 20) - array[1] * Renderer.getYScale()) - - ((ArrayVisualizer.windowHeight() - 20) - array[2] * Renderer.getYScale()); - - - int width = (int) (Renderer.getXScale() * (i + 1)) - Renderer.getOffset(); - - if(width > 0) { - if(Highlights.fancyFinishActive()) { - if(i < Highlights.getFancyFinishPosition()) { - lineFancy(this.mainRender, ArrayVisualizer.currentWidth()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - - drawFancyFinishLine(ArrayVisualizer.getLogBaseTwoOfLength(), i, Highlights.getFancyFinishPosition(), this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled()); - } - else if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) { - lineMark(this.mainRender, ArrayVisualizer.currentWidth(), ArrayVisualizer.colorEnabled(), ArrayVisualizer.analysisEnabled()); - } - else lineClear(this.mainRender, ArrayVisualizer.colorEnabled(), array, i, ArrayVisualizer.getCurrentLength(), ArrayVisualizer.currentWidth()); - - this.mainRender.drawLine(Renderer.getOffset() + 20, y, Renderer.getLineX() + 20, Renderer.getLineY()); - - Renderer.setLineX(Renderer.getOffset()); - Renderer.setLineY(y); - } - Renderer.setOffset(Renderer.getOffset() + width); - } - } -} \ No newline at end of file diff --git a/src/visuals/mesh/TriangleMesh.java b/src/visuals/mesh/TriangleMesh.java deleted file mode 100644 index 89cd5300..00000000 --- a/src/visuals/mesh/TriangleMesh.java +++ /dev/null @@ -1,138 +0,0 @@ -package visuals.mesh; - -import java.awt.Color; - -import main.ArrayVisualizer; -import utils.Highlights; -import utils.Renderer; -import visuals.Visual; - -/* - * -MIT License - -Copyright (c) 2019 w0rthy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - * - */ - -final public class TriangleMesh extends Visual { - public TriangleMesh(ArrayVisualizer ArrayVisualizer) { - super(ArrayVisualizer); - } - - //TODO: Change these to be more consistent between array lengths. These heights and counts are a bit random. - public static int getTriangleHeight(int length, double height) { - switch(length) { - case 2: height *= 20; break; - case 4: height *= 13; break; - case 8: height *= 8; break; - case 16: - case 32: height *= 4.4; break; - case 64: height *= 2.3; break; - case 128: height *= 2.35; break; - case 256: height *= 1.22; break; - default: height *= 1; - } - - return (int) height; - } - - public static int getTrianglesPerRow(int length, int trianglesPerColumn) { - int trianglesPerRow; - - switch(length) { - case 32: - case 64: trianglesPerRow = 4; break; - case 128: - case 256: trianglesPerRow = 8; break; - default: trianglesPerRow = Math.max(length / trianglesPerColumn, 2); - } - - return trianglesPerRow; - } - - @Override - public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - int trih = getTriangleHeight(ArrayVisualizer.getCurrentLength(), ArrayVisualizer.windowHeight() / 20); //Height of triangles to use, Width will be scaled accordingly - - int tripercol = (ArrayVisualizer.windowHeight() / trih) * 2; //Triangles per column - int triperrow = getTrianglesPerRow(ArrayVisualizer.getCurrentLength(), tripercol); //Triangles per row - - double triw = (double) ArrayVisualizer.windowWidth() / triperrow; //Width of triangles to use - - double curx = 0; - int cury = 15; - - int[] triptsx = new int[3]; - int[] triptsy = new int[3]; - - for(int i = 0; i < ArrayVisualizer.getCurrentLength(); i++){ - if(Highlights.containsPosition(i) && ArrayVisualizer.getCurrentLength() != 2) { - if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.WHITE); - else this.mainRender.setColor(Color.BLACK); - } - else { - //TODO: Clean up this visual trick - if(Highlights.fancyFinishActive() && (i < Highlights.getFancyFinishPosition() && i > Highlights.getFancyFinishPosition() - ArrayVisualizer.getLogBaseTwoOfLength())) { - this.mainRender.setColor(Color.GREEN); - } - else this.mainRender.setColor(getIntColor(array[i], ArrayVisualizer.getCurrentLength())); - } - //If i/triperrow is even, then triangle points right, else left - boolean direction = false; - if((i / triperrow) % 2 == 0) direction = true; - else direction = false; - - //Make the triangle - if(!direction) { - //Pointing right - triptsx[0] = (int) curx; - triptsx[1] = (int) curx; - curx += triw; - triptsx[2] = (int) curx; - - triptsy[0] = cury; - triptsy[2] = cury + (trih / 2); - triptsy[1] = cury + trih; - }else{ - //Pointing left - triptsx[2] = (int) curx; - curx += triw; - triptsx[0] = (int) curx; - triptsx[1] = (int) curx; - - triptsy[0] = cury; - triptsy[2] = cury + (trih / 2); - triptsy[1] = cury + trih; - } - - //Draw it - this.mainRender.fillPolygon(triptsx, triptsy, triptsx.length); - - //If at the end of a row, reset curx - //(i != 0 || i != currentLen - 1) - if((i + 1) % triperrow == 0){ - curx = 0; - cury += trih / 2; - } - } - } -} \ No newline at end of file diff --git a/src/visuals/HoopStack.java b/src/visuals/misc/HoopStack.java similarity index 81% rename from src/visuals/HoopStack.java rename to src/visuals/misc/HoopStack.java index e83d6039..d9b01ebc 100644 --- a/src/visuals/HoopStack.java +++ b/src/visuals/misc/HoopStack.java @@ -1,16 +1,17 @@ -package visuals; +package visuals.misc; import java.awt.Color; import main.ArrayVisualizer; import utils.Highlights; import utils.Renderer; +import visuals.Visual; /* * MIT License -Copyright (c) 2020 ArrayV 4.0 Team +Copyright (c) 2020-2021 ArrayV 4.0 Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -43,17 +44,19 @@ private void drawEllipseFromCenter(int x, int y, int rx, int ry) { @Override public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { - if (Renderer.auxActive) - return; + if(Renderer.auxActive) return; int width = ArrayVisualizer.windowWidth(); int height = ArrayVisualizer.windowHeight(); int length = ArrayVisualizer.getCurrentLength(); + + int radiusX = height / 3; + int radiusY = height / 9; + + this.mainRender.setStroke(ArrayVisualizer.getThinStroke()); for(int i = length - 1; i >= 0; i--) { double scale = (array[i] + 1) / (double) (length + 1); - int radiusX = height / 3; - int radiusY = height / 9; int y = (int) ((height - radiusY * 4) * i / (double) (length - 1)); @@ -62,11 +65,15 @@ public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Re else if(Highlights.containsPosition(i)) { if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.LIGHT_GRAY); - else this.mainRender.setColor(Color.WHITE); + else this.mainRender.setColor(Color.WHITE); + + this.mainRender.setStroke(ArrayVisualizer.getDefaultStroke()); } else this.mainRender.setColor(getIntColor(array[i], length)); this.drawEllipseFromCenter(width / 2, y + radiusY * 2, (int) (scale * radiusX + 0.5), (int) (scale * radiusY + 0.5)); + this.mainRender.setStroke(ArrayVisualizer.getThinStroke()); } + this.mainRender.setStroke(ArrayVisualizer.getDefaultStroke()); } } \ No newline at end of file diff --git a/src/visuals/misc/PixelMesh.java b/src/visuals/misc/PixelMesh.java new file mode 100644 index 00000000..0c26fd10 --- /dev/null +++ b/src/visuals/misc/PixelMesh.java @@ -0,0 +1,78 @@ +package visuals.misc; + +import java.awt.Color; + +import main.ArrayVisualizer; +import utils.Highlights; +import utils.Renderer; +import visuals.Visual; + +/* + * +MIT License + +Copyright (c) 2020-2021 ArrayV 4.0 Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class PixelMesh extends Visual { + public PixelMesh(ArrayVisualizer ArrayVisualizer) { + super(ArrayVisualizer); + } + + @Override + public void drawVisual(int[] array, ArrayVisualizer ArrayVisualizer, Renderer Renderer, Highlights Highlights) { + if(Renderer.auxActive) return; + + int width = ArrayVisualizer.windowWidth()-40; + int height = ArrayVisualizer.windowHeight()-50; + int length = ArrayVisualizer.getCurrentLength(); + + int sqrt = (int)Math.ceil(Math.sqrt(length)); + int square = sqrt*sqrt; + double scale = (double)length / square; + + int x = 0; + int y = 0; + double xStep = (double)width / sqrt; + double yStep = (double)height / sqrt; + + for(int i = 0; i < square; i++) { + int idx = (int)(i * scale); + if(Highlights.fancyFinishActive() && idx < Highlights.getFancyFinishPosition()) + this.mainRender.setColor(Color.GREEN); + + else if(Highlights.containsPosition(idx)) { + if(ArrayVisualizer.analysisEnabled()) this.mainRender.setColor(Color.LIGHT_GRAY); + else this.mainRender.setColor(Color.WHITE); + } + else this.mainRender.setColor(getIntColor(array[idx], length)); + + this.mainRender.fillRect(20 + (int)(x * xStep), 40 + (int)(y * yStep), + (int)((x+1)*xStep - x*xStep)+1, (int)((y+1)*yStep - y*yStep)+1); + + if(++x == sqrt) { + x = 0; + y++; + } + } + } +} \ No newline at end of file