Initial commit
This commit is contained in:
commit
445eb8f1c3
55 changed files with 6789 additions and 0 deletions
74
build.xml
Normal file
74
build.xml
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="ZomBDeepZoom" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project ZomBDeepZoom.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar-with-manifest: JAR building (if you are using a manifest)
|
||||
-do-jar-without-manifest: JAR building (if you are not using a manifest)
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="ZomBDeepZoom-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
1041
nbproject/build-impl.xml
Normal file
1041
nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load diff
0
nbproject/private/config.properties
Normal file
0
nbproject/private/config.properties
Normal file
1
nbproject/private/private.properties
Normal file
1
nbproject/private/private.properties
Normal file
|
@ -0,0 +1 @@
|
|||
user.properties.file=C:\\Users\\Yukari Yakumo\\.netbeans\\7.0\\build.properties
|
62
nbproject/project.properties
Normal file
62
nbproject/project.properties
Normal file
|
@ -0,0 +1,62 @@
|
|||
application.title=ZomBDeepZoom
|
||||
application.vendor=Administrator
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/ZomBDeepZoom.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.source=1.5
|
||||
javac.target=1.5
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}:\
|
||||
${libs.junit.classpath}:\
|
||||
${libs.junit_4.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
main.class=deepZoom.MandelAnimator
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project
|
||||
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
|
||||
# or test-sys-prop.name=value to set system properties for unit tests):
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
9
src/deepZoom/Main.java
Normal file
9
src/deepZoom/Main.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
package deepZoom;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//new MandelAnimator();
|
||||
|
||||
}
|
||||
}
|
334
src/deepZoom/MandelAnimator.java
Normal file
334
src/deepZoom/MandelAnimator.java
Normal file
|
@ -0,0 +1,334 @@
|
|||
package deepZoom;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.io.IOException;
|
||||
|
||||
import deepZoom.calculator.Calculator;
|
||||
import deepZoom.calculator.ParallelCalculator;
|
||||
import deepZoom.colorings.Coloring;
|
||||
import deepZoom.colorings.SmoothIterationsColoringBad;
|
||||
import deepZoom.fractals.Fractal;
|
||||
import deepZoom.fractals.Mandel;
|
||||
import deepZoom.fractals.MandelPrecision;
|
||||
import deepZoom.parameters.ZoomAnimation;
|
||||
import deepZoom.renderer.Layer;
|
||||
import deepZoom.renderer.Scene;
|
||||
import deepZoom.schedulers.AngularScheduler;
|
||||
import deepZoom.schedulers.CRTScheduler;
|
||||
import deepZoom.schedulers.ClockScheduler;
|
||||
import deepZoom.schedulers.DitherScheduler;
|
||||
import deepZoom.schedulers.FlowerScheduler;
|
||||
import deepZoom.schedulers.ModScheduler;
|
||||
import deepZoom.schedulers.PythagorasScheduler;
|
||||
import deepZoom.schedulers.RadialScheduler;
|
||||
import deepZoom.schedulers.RandomScheduler;
|
||||
import deepZoom.schedulers.Scheduler;
|
||||
import deepZoom.schedulers.SimpleScheduler;
|
||||
import deepZoom.schedulers.SpiralScheduler;
|
||||
import deepZoom.schedulers.SplitScheduler;
|
||||
import deepZoom.schedulers.SquareSpiralScheduler;
|
||||
import deepZoom.schedulers.XorScheduler;
|
||||
import deepZoom.viewports.Viewport;
|
||||
|
||||
import digisoft.custom.NumberFunctions;
|
||||
import digisoft.custom.awt.Color3f;
|
||||
import digisoft.custom.swing.ImageFunctions;
|
||||
import digisoft.custom.swing.RefreshListener;
|
||||
import digisoft.custom.swing.RefreshThread;
|
||||
import digisoft.custom.swing.gradient.Gradient;
|
||||
import digisoft.custom.swing.gradient.OpaqueGradient;
|
||||
import digisoft.custom.swing.window.PixelWindow;
|
||||
import digisoft.custom.util.geom.DoubleDouble;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @see date 2006/10/20
|
||||
*/
|
||||
public class MandelAnimator implements RefreshListener, Calculator, MouseListener {
|
||||
|
||||
private static final String SAVEPATH = "C:/Animation golden/";
|
||||
private static final int WIDTH = (int) (1024);
|
||||
private static final int HEIGHT = (int) (576);
|
||||
private static int FRAME_START = 1;
|
||||
private static final int FRAME_END = 3600;
|
||||
private static final int FRAME_STEP = 1;
|
||||
private static final boolean DO_ANTIALIAS = true;
|
||||
//Traditional Wikipedia
|
||||
private DoubleDouble centerX = new DoubleDouble(-0.7436438870371587, -3.628952515063387E-17);
|
||||
private DoubleDouble centerY = new DoubleDouble(0.13182590420531198, -1.2892807754956678E-17);
|
||||
//Line and cross
|
||||
//private DoubleDouble centerX = new DoubleDouble(-0.743646040973709, -4.790419761500457E-18);
|
||||
//private DoubleDouble centerY = new DoubleDouble(0.13182426946026354, 1.9785505600065397E-18);
|
||||
private static final double MIN_ZOOM = 1;
|
||||
private static final double MAX_ZOOM = 1e30;
|
||||
private static final int NUM_FRAMES = 3600;
|
||||
|
||||
public static void main(String[] args) {
|
||||
new MandelAnimator();
|
||||
}
|
||||
private static final int NUM_CPUS = Runtime.getRuntime().availableProcessors();
|
||||
private PixelWindow aaWindow = new PixelWindow(10, 10, MandelAnimator.WIDTH, MandelAnimator.HEIGHT);
|
||||
private PixelWindow iterWindow = new PixelWindow(10, 10, MandelAnimator.WIDTH, MandelAnimator.HEIGHT);
|
||||
private PixelWindow fractalWindow = new PixelWindow(10, 10, MandelAnimator.WIDTH, MandelAnimator.HEIGHT);
|
||||
private Viewport viewport = new Viewport();
|
||||
private Layer layer = new Layer();
|
||||
private ZoomAnimation animation = new ZoomAnimation();
|
||||
private Fractal fractal = new Mandel();
|
||||
private Coloring coloring = new SmoothIterationsColoringBad(makeGradient());
|
||||
private Scheduler[] schedulers = {new SpiralScheduler(10)};
|
||||
private int scheduler;
|
||||
private Scene scene = new Scene();
|
||||
private int frameNr;
|
||||
private boolean antialiasStep = false;
|
||||
private long runTime;
|
||||
private long frameTime;
|
||||
|
||||
public MandelAnimator() {
|
||||
File dirFile = new File(SAVEPATH);
|
||||
dirFile.mkdir();
|
||||
|
||||
int newSave = 0;
|
||||
for (int i = MandelAnimator.FRAME_START; i <= MandelAnimator.FRAME_END; i++) {
|
||||
File test = new File(MandelAnimator.SAVEPATH
|
||||
+ NumberFunctions.toStringFixedLength(i, 4) + ".png");
|
||||
if (!test.isFile()) {
|
||||
newSave = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
MandelAnimator.FRAME_START = newSave;
|
||||
|
||||
fractalWindow.addMouseListener(this);
|
||||
iterWindow.setTitle("Iter");
|
||||
aaWindow.setTitle("AA");
|
||||
|
||||
animation.setWidth(MandelAnimator.WIDTH);
|
||||
animation.setNumFrames(MandelAnimator.NUM_FRAMES);
|
||||
animation.setCenterX(centerX);
|
||||
animation.setCenterY(centerY);
|
||||
animation.setMagnStart(MandelAnimator.MIN_ZOOM);
|
||||
animation.setMagnEnd(MandelAnimator.MAX_ZOOM);
|
||||
animation.setBailout(128);
|
||||
animation.init();
|
||||
viewport.setSize(MandelAnimator.WIDTH, MandelAnimator.HEIGHT);
|
||||
viewport.setParameters(animation);
|
||||
fractal.setParameters(animation);
|
||||
coloring.setParameters(animation);
|
||||
|
||||
for (Scheduler s : schedulers) {
|
||||
s.setViewport(viewport);
|
||||
}
|
||||
|
||||
scene.setViewport(viewport);
|
||||
scene.setColorPixels(fractalWindow.pixels);
|
||||
scene.setIterMap(iterWindow.pixels);
|
||||
scene.setEdgeMap(aaWindow.pixels);
|
||||
scene.setNumCPUs(MandelAnimator.NUM_CPUS);
|
||||
|
||||
{
|
||||
layer.setFractal(fractal);
|
||||
layer.setColoring(coloring);
|
||||
scene.addLayer(layer);
|
||||
}
|
||||
|
||||
frameNr = MandelAnimator.FRAME_START;
|
||||
|
||||
runTime = frameTime = System.currentTimeMillis();
|
||||
ParallelCalculator.createCalculators(this, MandelAnimator.NUM_CPUS);
|
||||
new RefreshThread(this, 30).start();
|
||||
}
|
||||
|
||||
public static Gradient makeGradient() {
|
||||
final Color3f[] c = {
|
||||
new Color3f(14, 11, 82),
|
||||
new Color3f(14, 60, 165),
|
||||
new Color3f(78, 154, 220),
|
||||
new Color3f(176, 229, 255),
|
||||
new Color3f(249, 253, 239),
|
||||
new Color3f(249, 229, 96),
|
||||
new Color3f(249, 181, 15),
|
||||
new Color3f(217, 108, 3),
|
||||
new Color3f(134, 32, 13),
|
||||
new Color3f(57, 4, 35),
|
||||
new Color3f(14, 11, 82)};
|
||||
final float[] f = new float[c.length];
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
f[i] = i / (float) (c.length - 1);
|
||||
f[i] = (float) StrictMath.sqrt(f[i]);
|
||||
}
|
||||
|
||||
return new OpaqueGradient(f, c);
|
||||
}
|
||||
|
||||
/*
|
||||
public static Gradient makeGradient() {
|
||||
final Color3f[] c = {new Color3f(0, 0, 0f), //
|
||||
new Color3f(1, 0, 0f), //
|
||||
new Color3f(1, 1, 1f), // Red
|
||||
new Color3f(1, 0, 0f), //
|
||||
new Color3f(0, 0, 0f), //
|
||||
new Color3f(1, 0.4f, 0f), //
|
||||
new Color3f(1, 1, 1f), // Orange
|
||||
new Color3f(1, 0.4f, 0f), //
|
||||
new Color3f(0, 0, 0f), //
|
||||
new Color3f(1, 1, 0f), //
|
||||
new Color3f(1, 1, 1f), // Yellow
|
||||
new Color3f(1, 1, 0f), //
|
||||
new Color3f(0, 0, 0f), //
|
||||
new Color3f(0, 1, 0f), //
|
||||
new Color3f(1, 1, 1f), // Green
|
||||
new Color3f(0, 1, 0f), //
|
||||
new Color3f(0, 0, 0f), //
|
||||
new Color3f(0, 1, 1f), //
|
||||
new Color3f(1, 1, 1f), // Cyan
|
||||
new Color3f(0, 1, 1f), //
|
||||
new Color3f(0, 0, 0f), //
|
||||
new Color3f(0, 0, 1f), //
|
||||
new Color3f(1, 1, 1f), // Blue
|
||||
new Color3f(0, 0, 1f), //
|
||||
new Color3f(0, 0, 0f)};
|
||||
final float[] f = new float[c.length];
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
f[i] = i / (float) (c.length - 1);
|
||||
f[i] = (float) StrictMath.sqrt(f[i]);
|
||||
}
|
||||
|
||||
return new OpaqueGradient(f, c);
|
||||
} */
|
||||
|
||||
private void saveFrame() {
|
||||
try {
|
||||
ImageFunctions.savePNG(MandelAnimator.SAVEPATH + NumberFunctions.toStringFixedLength(frameNr, 4) + ".png", fractalWindow.pixels,
|
||||
MandelAnimator.WIDTH, MandelAnimator.HEIGHT);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyImage() {
|
||||
System.gc();
|
||||
fractalWindow.clear(0);
|
||||
iterWindow.clear(0);
|
||||
aaWindow.clear(0);
|
||||
}
|
||||
|
||||
private void nextFrame() {
|
||||
frameNr += MandelAnimator.FRAME_STEP;
|
||||
if (frameNr > MandelAnimator.FRAME_END) {
|
||||
// System.exit(0);
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareCalculation() {
|
||||
scheduler = NumberFunctions.RND.nextInt(schedulers.length);
|
||||
scene.setScheduler(schedulers[scheduler]);
|
||||
|
||||
if (!antialiasStep) {
|
||||
fractalWindow.setTitle(Integer.toString(frameNr) + " First pass");
|
||||
|
||||
animation.setFrame(frameNr);
|
||||
|
||||
System.out.println("Rough: " + frameNr + " magn=" + animation.getMagn() + " maxiter=" + animation.getMaxiter());
|
||||
|
||||
destroyImage();
|
||||
scene.initFrame();
|
||||
} else {
|
||||
fractalWindow.setTitle(Integer.toString(frameNr) + " Antialiasing");
|
||||
|
||||
animation.setFrame(frameNr);
|
||||
animation.setMaxiter(animation.getMaxiter() << 2);
|
||||
|
||||
System.out.println("AA: " + frameNr + " magn=" + animation.getMagn() + " maxiter=" + animation.getMaxiter());
|
||||
|
||||
scene.calcAntialiasMask();
|
||||
}
|
||||
|
||||
schedulers[scheduler].init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(int cpu) {
|
||||
if (!antialiasStep) {
|
||||
scene.render(cpu);
|
||||
} else {
|
||||
scene.renderAntialias(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculationCompleted() {
|
||||
if (!antialiasStep && MandelAnimator.DO_ANTIALIAS) {
|
||||
antialiasStep = true;
|
||||
} else {
|
||||
antialiasStep = false;
|
||||
|
||||
fractalWindow.repaintNow();
|
||||
iterWindow.repaintNow();
|
||||
saveFrame();
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
System.out.println("Time elapsed: " + (time - runTime) / 1e3 + " / " + (time - frameTime) / 1e3);
|
||||
if (time - frameTime < 2000) {
|
||||
try {
|
||||
Thread.sleep(2000 - time + frameTime);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
frameTime = System.currentTimeMillis();
|
||||
|
||||
nextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshing() {
|
||||
fractalWindow.repaintNow();
|
||||
iterWindow.repaintNow();
|
||||
aaWindow.repaintNow();
|
||||
if (antialiasStep) {
|
||||
aaWindow.setTitle("AA " + (int) (schedulers[scheduler].getProgress() * 1000) / 10f + "%");
|
||||
} else {
|
||||
iterWindow.setTitle("Iter " + (int) (schedulers[scheduler].getProgress() * 1000) / 10f + "%");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
|
||||
centerX = viewport.getPX(e.getX(), e.getY());
|
||||
centerY = viewport.getPY(e.getX(), e.getY());
|
||||
|
||||
System.out.println("/tprivate DoubleDouble/t/t/tcenterX/t/t/t= new DoubleDouble(" + centerX.hi + ", " + centerX.lo + ");");
|
||||
System.out.println("/tprivate DoubleDouble/t/t/tcenterY/t/t/t= new DoubleDouble(" + centerY.hi + ", " + centerY.lo + ");");
|
||||
} else if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
}
|
32
src/deepZoom/animation/Animation.java
Normal file
32
src/deepZoom/animation/Animation.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package deepZoom.animation;
|
||||
|
||||
import deepZoom.parameters.Parameters;
|
||||
|
||||
/**
|
||||
* Generic animation for fractals. Implementations define which parameters are
|
||||
* animated, though animation for the following quantities is supported: center,
|
||||
* magnitude, maxiter and bailout. Before the animation can be calculated, the
|
||||
* number of frames need also be known beforehand. After changing animation
|
||||
* parameters or number of frames, the animation needs to be initialized by
|
||||
* calling init().
|
||||
*
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public abstract class Animation extends Parameters {
|
||||
|
||||
protected int numFrames;
|
||||
|
||||
public void setNumFrames(int numFrames) {
|
||||
this.numFrames = numFrames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the animation sequence. Call after each change to
|
||||
* initial/final parameters or number of frames.
|
||||
*/
|
||||
public abstract void init();
|
||||
|
||||
public abstract void setFrame(int frameNr);
|
||||
}
|
69
src/deepZoom/animation/ZoomAnimation.java
Normal file
69
src/deepZoom/animation/ZoomAnimation.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
package deepZoom.animation;
|
||||
|
||||
import digisoft.custom.util.geom.DoubleDouble;
|
||||
|
||||
/**
|
||||
* Animation that just zooms. The center parameters and bailout are not
|
||||
* animated, and the zooming position is the center of the fractal. ie. set the
|
||||
* center of the fractal to the center of thezoomed frame. The maxiter is also
|
||||
* animated to account for constant detail with maximum speed throughout the
|
||||
* animation. For this, the width of the frame in pixels is also required.
|
||||
* Bailout is also not animated.
|
||||
*
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public class ZoomAnimation extends Animation {
|
||||
|
||||
private int width;
|
||||
private double magnStart;
|
||||
private double magnEnd;
|
||||
private double factorMagn;
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNumFrames(int numFrames) {
|
||||
this.numFrames = numFrames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCenterX(DoubleDouble centerX) {
|
||||
this.centerX = centerX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCenterY(DoubleDouble centerY) {
|
||||
this.centerY = centerY;
|
||||
}
|
||||
|
||||
public void setMagnStart(double magnStart) {
|
||||
this.magnStart = magnStart;
|
||||
}
|
||||
|
||||
public void setMagnEnd(double magnEnd) {
|
||||
this.magnEnd = magnEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBailout(double bailout) {
|
||||
this.bailout = bailout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
factorMagn = StrictMath.pow(magnEnd / magnStart, 1.0 / (numFrames - 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFrame(int frameNr) {
|
||||
magn = magnStart * StrictMath.pow(factorMagn, frameNr - 1);
|
||||
|
||||
maxiter = (long) (width * StrictMath.pow(magn, -0.5));
|
||||
|
||||
System.out.println(magn);
|
||||
}
|
||||
}
|
15
src/deepZoom/calculator/Calculator.java
Normal file
15
src/deepZoom/calculator/Calculator.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package deepZoom.calculator;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date Apr 19, 2009
|
||||
*/
|
||||
public interface Calculator {
|
||||
|
||||
public void prepareCalculation();
|
||||
|
||||
public void calculate(int cpu);
|
||||
|
||||
public void calculationCompleted();
|
||||
}
|
93
src/deepZoom/calculator/ParallelCalculator.java
Normal file
93
src/deepZoom/calculator/ParallelCalculator.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
package deepZoom.calculator;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date Apr 19, 2009
|
||||
*/
|
||||
public class ParallelCalculator implements Runnable {
|
||||
|
||||
private static int NUM_CPUS;
|
||||
private static boolean[] WAIT;
|
||||
private static boolean[] GO;
|
||||
|
||||
public static void createCalculators(Calculator calculator, int numCPUs) {
|
||||
ParallelCalculator.NUM_CPUS = numCPUs;
|
||||
|
||||
ParallelCalculator.WAIT = new boolean[numCPUs];
|
||||
ParallelCalculator.GO = new boolean[numCPUs];
|
||||
|
||||
for (int i = 0; i < numCPUs; i++) {
|
||||
new ParallelCalculator(calculator, i);
|
||||
}
|
||||
}
|
||||
private int cpu;
|
||||
private Calculator calculator;
|
||||
|
||||
private ParallelCalculator(Calculator calculator, int cpu) {
|
||||
this.calculator = calculator;
|
||||
this.cpu = cpu;
|
||||
|
||||
System.out.println("Starting core " + cpu);
|
||||
|
||||
prepare();
|
||||
new Thread(this).start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
calculator.calculate(cpu);
|
||||
syncWithOthers();
|
||||
}
|
||||
}
|
||||
|
||||
private void prepare() {
|
||||
if (cpu == 0) {
|
||||
Arrays.fill(ParallelCalculator.WAIT, true);
|
||||
Arrays.fill(ParallelCalculator.GO, true);
|
||||
|
||||
calculator.prepareCalculation();
|
||||
}
|
||||
}
|
||||
|
||||
private void syncWithOthers() {
|
||||
ParallelCalculator.WAIT[cpu] = false;
|
||||
|
||||
if (cpu == 0) {
|
||||
while (true) {
|
||||
boolean done = true;
|
||||
for (int i = ParallelCalculator.NUM_CPUS - 1; i >= 0; i--) {
|
||||
if (ParallelCalculator.WAIT[i]) {
|
||||
done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.yield();
|
||||
}
|
||||
|
||||
// All threads done.
|
||||
|
||||
calculator.calculationCompleted();
|
||||
prepare();
|
||||
|
||||
Arrays.fill(ParallelCalculator.WAIT, true);
|
||||
Arrays.fill(ParallelCalculator.GO, true);
|
||||
} else {
|
||||
while (!ParallelCalculator.GO[cpu]) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParallelCalculator.GO[cpu] = false;
|
||||
}
|
||||
}
|
22
src/deepZoom/colorings/Coloring.java
Normal file
22
src/deepZoom/colorings/Coloring.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package deepZoom.colorings;
|
||||
|
||||
import deepZoom.parameters.Parameters;
|
||||
import deepZoom.renderer.PointInfo;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 1, 2009
|
||||
*/
|
||||
public abstract class Coloring {
|
||||
|
||||
protected Parameters parameters;
|
||||
|
||||
public void setParameters(Parameters parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public abstract void initParameters();
|
||||
|
||||
public abstract int getColor(PointInfo resultSet);
|
||||
}
|
26
src/deepZoom/colorings/GradientColoring.java
Normal file
26
src/deepZoom/colorings/GradientColoring.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package deepZoom.colorings;
|
||||
|
||||
import deepZoom.renderer.PointInfo;
|
||||
|
||||
import digisoft.custom.swing.gradient.Gradient;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public abstract class GradientColoring extends Coloring {
|
||||
|
||||
protected Gradient gradient;
|
||||
|
||||
public GradientColoring(Gradient gradient) {
|
||||
this.gradient = gradient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(PointInfo resultSet) {
|
||||
return gradient.get(getIndex(resultSet) % 1);
|
||||
}
|
||||
|
||||
public abstract float getIndex(PointInfo resultSet);
|
||||
}
|
37
src/deepZoom/colorings/SmoothIterationsColoringBad.java
Normal file
37
src/deepZoom/colorings/SmoothIterationsColoringBad.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package deepZoom.colorings;
|
||||
|
||||
import deepZoom.renderer.PointInfo;
|
||||
|
||||
import digisoft.custom.math.NumberConstants;
|
||||
import digisoft.custom.swing.gradient.Gradient;
|
||||
import digisoft.custom.util.geom.DoubleDouble;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 1, 2009
|
||||
*/
|
||||
public class SmoothIterationsColoringBad extends GradientColoring {
|
||||
|
||||
private double logLogBailout;
|
||||
|
||||
public SmoothIterationsColoringBad(Gradient gradient) {
|
||||
super(gradient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initParameters() {
|
||||
logLogBailout = StrictMath.log(StrictMath.log(parameters.getBailout()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getIndex(PointInfo resultSet) {
|
||||
long i = resultSet.lastIter;
|
||||
DoubleDouble zx = resultSet.lastZX;
|
||||
DoubleDouble zy = resultSet.lastZY;
|
||||
|
||||
double r = StrictMath.sqrt(zx.hi * zx.hi + zy.hi * zy.hi);
|
||||
double c = i - 1.28 + (logLogBailout - StrictMath.log(StrictMath.log(r))) * NumberConstants.Q1LOG2;
|
||||
return (float) (StrictMath.log(c / 64 + 1) / NumberConstants.LOG2 + 0.45);
|
||||
}
|
||||
}
|
29
src/deepZoom/fractals/Fractal.java
Normal file
29
src/deepZoom/fractals/Fractal.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package deepZoom.fractals;
|
||||
|
||||
import deepZoom.parameters.Parameters;
|
||||
import deepZoom.renderer.PointInfo;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/01
|
||||
*/
|
||||
public abstract class Fractal {
|
||||
|
||||
protected Parameters parameters;
|
||||
|
||||
public void setParameters(Parameters parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public abstract void initFrame();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param result
|
||||
* float array with {gradient index, last iter}
|
||||
*/
|
||||
public abstract void calcPoint(PointInfo pointInfo);
|
||||
}
|
119
src/deepZoom/fractals/Mandel.java
Normal file
119
src/deepZoom/fractals/Mandel.java
Normal file
|
@ -0,0 +1,119 @@
|
|||
package deepZoom.fractals;
|
||||
|
||||
import deepZoom.renderer.PointInfo;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/07/09
|
||||
*/
|
||||
public class Mandel extends Fractal {
|
||||
|
||||
private static final double PRIODICITY_EPS = 1e-17;
|
||||
|
||||
@Override
|
||||
public void initFrame() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcPoint(PointInfo pointInfo) {
|
||||
double zx;
|
||||
double zy;
|
||||
double xx;
|
||||
double yy;
|
||||
|
||||
double bailout = parameters.getBailout();
|
||||
long maxiter = parameters.getMaxiter();
|
||||
|
||||
// Calculate viewport.
|
||||
double px = pointInfo.px.hi;
|
||||
double py = pointInfo.py.hi;
|
||||
|
||||
// Main bulb check.
|
||||
zx = 4 * (px * px + py * py);
|
||||
xx = 2 * px;
|
||||
zy = zx + 4 * xx;
|
||||
if (zy < -3.75) {
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = maxiter;
|
||||
pointInfo.lastZX.hi = px;
|
||||
pointInfo.lastZY.hi = py;
|
||||
return;
|
||||
}
|
||||
|
||||
// Cardoid check.
|
||||
zy = zx - xx + 0.25;
|
||||
xx = xx + zy - 0.5;
|
||||
xx *= xx;
|
||||
if (zy > xx) {
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = maxiter;
|
||||
pointInfo.lastZX.hi = px;
|
||||
pointInfo.lastZY.hi = py;
|
||||
return;
|
||||
}
|
||||
|
||||
zx = px;
|
||||
zy = py;
|
||||
|
||||
// Initial maximum period to detect.
|
||||
int check = 3;
|
||||
// Maximum period doubles every iterations:
|
||||
int whenupdate = 10;
|
||||
// Period history registers.
|
||||
double hx = 0;
|
||||
double hy = 0;
|
||||
|
||||
// long int because maxiter goes above 2**31 bits
|
||||
for (long i = 1; i <= 50000; i++) {
|
||||
// Precalculate squares.
|
||||
xx = zx * zx;
|
||||
yy = zy * zy;
|
||||
|
||||
// Check bailout.
|
||||
if (xx + yy > bailout) {
|
||||
pointInfo.inside = false;
|
||||
pointInfo.lastIter = i;
|
||||
pointInfo.lastZX.hi = zx;
|
||||
pointInfo.lastZY.hi = zy;
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate
|
||||
zy = 2 * zx * zy + py;
|
||||
zx = xx - yy + px;
|
||||
|
||||
// Periodicity check.
|
||||
double d = zx - hx;
|
||||
if (d > 0.0 ? d < Mandel.PRIODICITY_EPS : d > -Mandel.PRIODICITY_EPS) {
|
||||
d = zy - hy;
|
||||
if (d > 0.0 ? d < Mandel.PRIODICITY_EPS : d > -Mandel.PRIODICITY_EPS) {
|
||||
// Period found.
|
||||
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = i; // & check
|
||||
pointInfo.lastZX.hi = zx;
|
||||
pointInfo.lastZY.hi = zy;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((i & check) == 0) {
|
||||
if (--whenupdate == 0) {
|
||||
whenupdate = 10;
|
||||
check <<= 1;
|
||||
check++;
|
||||
}
|
||||
// period = 0;
|
||||
hx = zx;
|
||||
hy = zy;
|
||||
}
|
||||
}
|
||||
|
||||
// Maxiter reached.
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = maxiter;
|
||||
pointInfo.lastZX.hi = zx;
|
||||
pointInfo.lastZY.hi = zy;
|
||||
return;
|
||||
}
|
||||
}
|
151
src/deepZoom/fractals/MandelPrecision.java
Normal file
151
src/deepZoom/fractals/MandelPrecision.java
Normal file
|
@ -0,0 +1,151 @@
|
|||
package deepZoom.fractals;
|
||||
|
||||
import deepZoom.renderer.PointInfo;
|
||||
|
||||
import digisoft.custom.util.geom.DoubleDouble;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/07/09
|
||||
*/
|
||||
public class MandelPrecision extends Fractal {
|
||||
|
||||
private static final double PRIODICITY_EPS = 1e-17;
|
||||
|
||||
@Override
|
||||
public void initFrame() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calcPoint(PointInfo pointInfo) {
|
||||
DoubleDouble zx = new DoubleDouble();
|
||||
DoubleDouble zy = new DoubleDouble();
|
||||
DoubleDouble xx = new DoubleDouble();
|
||||
DoubleDouble yy = new DoubleDouble();
|
||||
DoubleDouble temp = new DoubleDouble();
|
||||
|
||||
double bailout = parameters.getBailout();
|
||||
long maxiter = parameters.getMaxiter();
|
||||
|
||||
// Calculate viewport.
|
||||
// DoubleDouble px = this.viewport.getPX(x, y);
|
||||
// DoubleDouble py = this.viewport.getPY(x, y);
|
||||
DoubleDouble px = pointInfo.px;
|
||||
DoubleDouble py = pointInfo.py;
|
||||
|
||||
// Main bulb check.
|
||||
// zx = 4 * (px * px + py * py);
|
||||
zy.set(py);
|
||||
zy.sqrSelf();
|
||||
zx.set(px);
|
||||
zx.sqrSelf();
|
||||
zx.addSelf(zy);
|
||||
zx.mulSelf(4);
|
||||
// temp = 2 * px
|
||||
xx.set(px);
|
||||
xx.mulSelf(2);
|
||||
// zy = zx + 4 * temp
|
||||
zy.set(xx);
|
||||
zy.mulSelf(4);
|
||||
zy.addSelf(zx);
|
||||
if (zy.hi < -3.75) {
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = maxiter;
|
||||
pointInfo.lastZX = px;
|
||||
pointInfo.lastZY = py;
|
||||
return;
|
||||
}
|
||||
|
||||
// Cardoid check.
|
||||
// zy = zx - temp + 0.25;
|
||||
zy.set(zx);
|
||||
zy.subSelf(xx);
|
||||
zy.addSelf(0.25);
|
||||
// temp = (temp + zy - 0.5)**2;
|
||||
xx.addSelf(zy);
|
||||
xx.addSelf(-0.5);
|
||||
xx.sqrSelf();
|
||||
// if (zy > temp)
|
||||
if (zy.hi > xx.hi) {
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = maxiter;
|
||||
pointInfo.lastZX = px;
|
||||
pointInfo.lastZY = py;
|
||||
return;
|
||||
}
|
||||
|
||||
zx.set(px);
|
||||
zy.set(py);
|
||||
|
||||
// Initial maximum period to detect.
|
||||
int check = 3;
|
||||
// Maximum period doubles every iterations:
|
||||
int whenupdate = 10;
|
||||
// Period history registers.
|
||||
double hx = 0;
|
||||
double hy = 0;
|
||||
|
||||
// long int because maxiter goes above 2**31 bits
|
||||
for (long i = 1; i <= 50000; i++) {
|
||||
// Precalculate squares.
|
||||
xx.set(zx);
|
||||
xx.sqrSelf();
|
||||
yy.set(zy);
|
||||
yy.sqrSelf();
|
||||
|
||||
// Check bailout.
|
||||
temp.set(xx);
|
||||
temp.addSelf(yy);
|
||||
if (temp.hi > bailout) {
|
||||
pointInfo.inside = false;
|
||||
pointInfo.lastIter = i;
|
||||
pointInfo.lastZX = zx;
|
||||
pointInfo.lastZY = zy;
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate
|
||||
// y' = y * x * 2 + cy
|
||||
zy.mulSelf(zx);
|
||||
zy.addSelf(zy);
|
||||
zy.addSelf(py);
|
||||
// x' = xx - yy + px
|
||||
xx.subSelf(yy);
|
||||
zx.set(xx);
|
||||
zx.addSelf(px);
|
||||
|
||||
// Periodicity check.
|
||||
double d = zx.hi - hx;
|
||||
if (d > 0.0 ? d < MandelPrecision.PRIODICITY_EPS : d > -MandelPrecision.PRIODICITY_EPS) {
|
||||
d = zy.hi - hy;
|
||||
if (d > 0.0 ? d < MandelPrecision.PRIODICITY_EPS : d > -MandelPrecision.PRIODICITY_EPS) {
|
||||
// Period found.
|
||||
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = i; // & check
|
||||
pointInfo.lastZX = zx;
|
||||
pointInfo.lastZY = zy;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((i & check) == 0) {
|
||||
if (--whenupdate == 0) {
|
||||
whenupdate = 10;
|
||||
check <<= 1;
|
||||
check++;
|
||||
}
|
||||
// period = 0;
|
||||
hx = zx.hi;
|
||||
hy = zy.hi;
|
||||
}
|
||||
}
|
||||
|
||||
// Maxiter reached.
|
||||
pointInfo.inside = true;
|
||||
pointInfo.lastIter = maxiter;
|
||||
pointInfo.lastZX = zx;
|
||||
pointInfo.lastZY = zy;
|
||||
return;
|
||||
}
|
||||
}
|
30
src/deepZoom/parameters/Animation.java
Normal file
30
src/deepZoom/parameters/Animation.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package deepZoom.parameters;
|
||||
|
||||
/**
|
||||
* Generic animation for fractals. Implementations define which parameters are
|
||||
* animated, though animation for the following quantities is supported: center,
|
||||
* magnitude, maxiter and bailout. Before the animation can be calculated, the
|
||||
* number of frames need also be known beforehand. After changing animation
|
||||
* parameters or number of frames, the animation needs to be initialized by
|
||||
* calling init().
|
||||
*
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public abstract class Animation extends Parameters {
|
||||
|
||||
protected int numFrames;
|
||||
|
||||
public void setNumFrames(int numFrames) {
|
||||
this.numFrames = numFrames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the animation sequence. Call after each change to
|
||||
* initial/final parameters or number of frames.
|
||||
*/
|
||||
public abstract void init();
|
||||
|
||||
public abstract void setFrame(int frameNr);
|
||||
}
|
57
src/deepZoom/parameters/Parameters.java
Normal file
57
src/deepZoom/parameters/Parameters.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
package deepZoom.parameters;
|
||||
|
||||
import digisoft.custom.util.geom.DoubleDouble;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public class Parameters {
|
||||
|
||||
protected DoubleDouble centerX = new DoubleDouble();
|
||||
protected DoubleDouble centerY = new DoubleDouble();
|
||||
protected double magn;
|
||||
protected long maxiter;
|
||||
protected double bailout;
|
||||
|
||||
public void setCenterX(DoubleDouble centerX) {
|
||||
this.centerX = centerX;
|
||||
}
|
||||
|
||||
public DoubleDouble getCenterX() {
|
||||
return centerX;
|
||||
}
|
||||
|
||||
public void setCenterY(DoubleDouble centerY) {
|
||||
this.centerY = centerY;
|
||||
}
|
||||
|
||||
public DoubleDouble getCenterY() {
|
||||
return centerY;
|
||||
}
|
||||
|
||||
public void setMagn(double magn) {
|
||||
this.magn = magn;
|
||||
}
|
||||
|
||||
public double getMagn() {
|
||||
return magn;
|
||||
}
|
||||
|
||||
public void setMaxiter(long maxiter) {
|
||||
this.maxiter = maxiter;
|
||||
}
|
||||
|
||||
public long getMaxiter() {
|
||||
return maxiter;
|
||||
}
|
||||
|
||||
public void setBailout(double bailout) {
|
||||
this.bailout = bailout;
|
||||
}
|
||||
|
||||
public double getBailout() {
|
||||
return bailout;
|
||||
}
|
||||
}
|
55
src/deepZoom/parameters/ZoomAnimation.java
Normal file
55
src/deepZoom/parameters/ZoomAnimation.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package deepZoom.parameters;
|
||||
|
||||
/**
|
||||
* Animation that just zooms. The center parameters and bailout are not
|
||||
* animated, and the zooming position is the center of the fractal. ie. set the
|
||||
* center of the fractal to the center of thezoomed frame. The maxiter is also
|
||||
* animated to account for constant detail with maximum speed throughout the
|
||||
* animation. For this, the width of the frame in pixels is also required.
|
||||
* Bailout is also not animated.
|
||||
*
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public class ZoomAnimation extends Animation {
|
||||
|
||||
private int width;
|
||||
private double magnStart;
|
||||
private double magnEnd;
|
||||
private double factorMagn;
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNumFrames(int numFrames) {
|
||||
this.numFrames = numFrames;
|
||||
}
|
||||
|
||||
public void setMagnStart(double magnStart) {
|
||||
this.magnStart = magnStart;
|
||||
}
|
||||
|
||||
public void setMagnEnd(double magnEnd) {
|
||||
this.magnEnd = magnEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBailout(double bailout) {
|
||||
this.bailout = bailout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
factorMagn = StrictMath.pow(magnEnd / magnStart, 1.0 / (numFrames - 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFrame(int frameNr) {
|
||||
magn = magnStart * StrictMath.pow(factorMagn, frameNr - 1);
|
||||
|
||||
maxiter = (long) (width * StrictMath.sqrt(magn));
|
||||
}
|
||||
}
|
28
src/deepZoom/renderer/Layer.java
Normal file
28
src/deepZoom/renderer/Layer.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package deepZoom.renderer;
|
||||
|
||||
import deepZoom.colorings.Coloring;
|
||||
import deepZoom.fractals.Fractal;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 3, 2009
|
||||
*/
|
||||
public class Layer {
|
||||
|
||||
protected Fractal fractal;
|
||||
protected Coloring coloring;
|
||||
|
||||
public void setFractal(Fractal fractal) {
|
||||
this.fractal = fractal;
|
||||
}
|
||||
|
||||
public void setColoring(Coloring coloring) {
|
||||
this.coloring = coloring;
|
||||
}
|
||||
|
||||
public void initFrame() {
|
||||
fractal.initFrame();
|
||||
coloring.initParameters();
|
||||
}
|
||||
}
|
21
src/deepZoom/renderer/PointInfo.java
Normal file
21
src/deepZoom/renderer/PointInfo.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package deepZoom.renderer;
|
||||
|
||||
import digisoft.custom.util.geom.DoubleDouble;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public class PointInfo {
|
||||
|
||||
public DoubleDouble px;
|
||||
public DoubleDouble py;
|
||||
public boolean inside;
|
||||
public long lastIter;
|
||||
public DoubleDouble lastZX = new DoubleDouble();
|
||||
public DoubleDouble lastZY = new DoubleDouble();
|
||||
protected int antialiasFactor;
|
||||
protected int antialiasReach;
|
||||
protected int antialiasArea;
|
||||
}
|
221
src/deepZoom/renderer/Scene.java
Normal file
221
src/deepZoom/renderer/Scene.java
Normal file
|
@ -0,0 +1,221 @@
|
|||
package deepZoom.renderer;
|
||||
|
||||
import deepZoom.schedulers.PriorityPoint;
|
||||
import deepZoom.schedulers.Scheduler;
|
||||
import deepZoom.viewports.Viewport;
|
||||
|
||||
import digisoft.custom.awt.Color3f;
|
||||
import digisoft.custom.awt.Color3fConst;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date May 2, 2009
|
||||
*/
|
||||
public class Scene {
|
||||
|
||||
private Viewport viewport;
|
||||
private Scheduler scheduler;
|
||||
private int[] pixels;
|
||||
private int[] iterMap;
|
||||
private int[] edgeMap;
|
||||
private Color3f[] colors;
|
||||
private int[] mask;
|
||||
// Multiple layer support unfinished!
|
||||
private Layer layer;
|
||||
private int width;
|
||||
private int height;
|
||||
private int area = -1;
|
||||
|
||||
public void setViewport(Viewport viewport) {
|
||||
this.viewport = viewport;
|
||||
}
|
||||
|
||||
public void setScheduler(Scheduler scheduler) {
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
public void setColorPixels(int[] pixels) {
|
||||
this.pixels = pixels;
|
||||
}
|
||||
|
||||
public void setIterMap(int[] iterMap) {
|
||||
this.iterMap = iterMap;
|
||||
}
|
||||
|
||||
public void setEdgeMap(int[] edgeMap) {
|
||||
this.edgeMap = edgeMap;
|
||||
}
|
||||
|
||||
public void addLayer(Layer layer) {
|
||||
this.layer = layer;
|
||||
}
|
||||
|
||||
public void initFrame() {
|
||||
viewport.initParameters();
|
||||
layer.initFrame();
|
||||
|
||||
width = viewport.width;
|
||||
height = viewport.height;
|
||||
|
||||
if (area != width * height) {
|
||||
area = width * height;
|
||||
|
||||
colors = new Color3f[area];
|
||||
mask = new int[area];
|
||||
|
||||
for (int i = 0; i < area; i++) {
|
||||
colors[i] = new Color3f();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < area; i++) {
|
||||
colors[i].set(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(PointInfo pointInfo, PriorityPoint point) {
|
||||
int p = point.x + point.y * width;
|
||||
|
||||
viewport.getPoint(point.x, point.y, pointInfo);
|
||||
layer.fractal.calcPoint(pointInfo);
|
||||
int iter = (int) pointInfo.lastIter;
|
||||
boolean inside = pointInfo.inside;
|
||||
|
||||
iterMap[p] = iter;
|
||||
edgeMap[p] = inside ? 0 : iter;
|
||||
|
||||
if (!inside) {
|
||||
colors[p].addSelf(layer.coloring.getColor(pointInfo));
|
||||
}
|
||||
|
||||
pixels[p] = colors[p].getRGB();
|
||||
}
|
||||
|
||||
public void calcAntialiasMask() {
|
||||
int p = -1;
|
||||
for (int y = 0; y < height; y++) {
|
||||
search:
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (x == 0 || y == 0 || x + 1 == width || y + 1 == height) {
|
||||
mask[++p] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
mask[++p] = 0;
|
||||
|
||||
int iters = edgeMap[p];
|
||||
|
||||
for (int v = y - 1; v <= y + 1; v++) {
|
||||
for (int u = x - 1; u <= x + 1; u++) {
|
||||
if (u >= 0 && v >= 0 && u < width && v < height) {
|
||||
int i = StrictMath.abs(edgeMap[u + v * width]);
|
||||
if (i != iters) {
|
||||
mask[p] = 1;
|
||||
continue search;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (mask[p] != 0) {
|
||||
int i = 0;
|
||||
for (int v = y - 1; v <= y + 1; v++) {
|
||||
for (int u = x - 1; u <= x + 1; u++) {
|
||||
if (u >= 0 && v >= 0 && u < width && v < height) {
|
||||
int iters = StrictMath.abs(iterMap[u + v * width]);
|
||||
if (i < iters) {
|
||||
i = iters;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
double d = 32 / StrictMath.log(i);
|
||||
mask[p] = StrictMath.min((int) (d * d), 15);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
p = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
edgeMap[p] = Color3fConst.DOS_PALETTE[mask[p++] & 0xFF];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void renderAntialias(PointInfo pointInfo, PriorityPoint point) {
|
||||
int p = point.x + point.y * width;
|
||||
|
||||
if (mask[p] != 0) {
|
||||
pointInfo.antialiasFactor = 5;
|
||||
pointInfo.antialiasReach = pointInfo.antialiasFactor / 2;
|
||||
pointInfo.antialiasArea = pointInfo.antialiasFactor * pointInfo.antialiasFactor;
|
||||
|
||||
calcAntialiasPixel(pointInfo, p, point);
|
||||
edgeMap[p] = (edgeMap[p] & 0xFCFCFC) >> 2;
|
||||
|
||||
colors[p].scaleSelf(1f / pointInfo.antialiasArea);
|
||||
pixels[p] = colors[p].getRGB();
|
||||
}
|
||||
}
|
||||
|
||||
private void calcAntialiasPixel(PointInfo pointInfo, int p, PriorityPoint point) {
|
||||
int reach = pointInfo.antialiasReach;
|
||||
double factor = 1.0 / pointInfo.antialiasFactor;
|
||||
for (int x = -reach; x <= reach; x++) {
|
||||
double dx = x * factor;
|
||||
for (int y = -reach; y <= reach; y++) {
|
||||
double dy = y * factor;
|
||||
|
||||
if ((x | y) != 0) {
|
||||
viewport.getPoint(point.x + dx, point.y + dy, pointInfo);
|
||||
layer.fractal.calcPoint(pointInfo);
|
||||
boolean inside = pointInfo.inside;
|
||||
|
||||
if (!inside) {
|
||||
colors[p].addSelf(layer.coloring.getColor(pointInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private PointInfo[] pointInfos;
|
||||
|
||||
public void setNumCPUs(int numCPUs) {
|
||||
if (pointInfos == null || pointInfos.length != numCPUs) {
|
||||
pointInfos = new PointInfo[numCPUs];
|
||||
for (int cpu = 0; cpu < numCPUs; cpu++) {
|
||||
pointInfos[cpu] = new PointInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void render(int cpu) {
|
||||
while (true) {
|
||||
PriorityPoint point = scheduler.poll();
|
||||
if (point == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.render(pointInfos[cpu], point);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderAntialias(int cpu) {
|
||||
while (true) {
|
||||
PriorityPoint point = scheduler.poll();
|
||||
if (point == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.renderAntialias(pointInfos[cpu], point);
|
||||
}
|
||||
}
|
||||
}
|
32
src/deepZoom/schedulers/AngularScheduler.java
Normal file
32
src/deepZoom/schedulers/AngularScheduler.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/02
|
||||
*/
|
||||
public class AngularScheduler extends Scheduler {
|
||||
|
||||
private int bands;
|
||||
|
||||
public AngularScheduler(int bands) {
|
||||
this.bands = bands;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
double dy = y - (height - 0.875) * 0.5;
|
||||
for (int x = 0; x < width; x++) {
|
||||
double dx = x - (width - 0.75) * 0.5;
|
||||
|
||||
double a = StrictMath.abs((StrictMath.atan2(dy, -dx) / (2 * StrictMath.PI) + 0.5) * bands % 1 - 0.5);
|
||||
add(new PriorityPoint(i, x, y, -a));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
src/deepZoom/schedulers/CRTScheduler.java
Normal file
24
src/deepZoom/schedulers/CRTScheduler.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/05
|
||||
*/
|
||||
public class CRTScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int dy = height - y;
|
||||
for (int x = 0; x < width; x++) {
|
||||
int dx = width - x;
|
||||
add(new PriorityPoint(i, x, y, -x * y * dx * dy));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
src/deepZoom/schedulers/ClockScheduler.java
Normal file
24
src/deepZoom/schedulers/ClockScheduler.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/02
|
||||
*/
|
||||
public class ClockScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
double dy = y - (height - 0.875) * 0.5;
|
||||
for (int x = 0; x < width; x++) {
|
||||
double dx = x - (width - 0.75) * 0.5;
|
||||
add(new PriorityPoint(i, x, y, Math.atan2(-dy, -dx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
src/deepZoom/schedulers/DitherScheduler.java
Normal file
25
src/deepZoom/schedulers/DitherScheduler.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/03
|
||||
*/
|
||||
public class DitherScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int dy = Integer.reverse(y) >>> 16;
|
||||
for (int x = 0; x < width; x++) {
|
||||
int dx = Integer.reverse(x) >>> 16;
|
||||
|
||||
add(new PriorityPoint(i, x, y, dx + dy));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
src/deepZoom/schedulers/FlowerScheduler.java
Normal file
36
src/deepZoom/schedulers/FlowerScheduler.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/03
|
||||
*/
|
||||
public class FlowerScheduler extends Scheduler {
|
||||
|
||||
private int petals;
|
||||
private double petalSize;
|
||||
|
||||
public FlowerScheduler(int petals, double petalSize) {
|
||||
this.petals = petals;
|
||||
this.petalSize = 4 / petalSize + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
double dy = y - (height - 0.875) * 0.5;
|
||||
for (int x = 0; x < width; x++) {
|
||||
double dx = x - (width - 0.75) * 0.5;
|
||||
|
||||
double a = StrictMath.atan2(dy, -dx) * petals;
|
||||
double r = StrictMath.sqrt(dx * dx + dy * dy);
|
||||
dx = r * (StrictMath.cos(a) + petalSize);
|
||||
add(new PriorityPoint(i, x, y, dx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
src/deepZoom/schedulers/ModScheduler.java
Normal file
22
src/deepZoom/schedulers/ModScheduler.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/05
|
||||
*/
|
||||
public class ModScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
add(new PriorityPoint(i, x, y, x % (y + 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
src/deepZoom/schedulers/PriorityPoint.java
Normal file
32
src/deepZoom/schedulers/PriorityPoint.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/17
|
||||
*/
|
||||
public class PriorityPoint implements Comparable<PriorityPoint> {
|
||||
|
||||
public int layer;
|
||||
public int x;
|
||||
public int y;
|
||||
private double priority;
|
||||
|
||||
public PriorityPoint(int layer, int x, int y, double priority) {
|
||||
this.layer = layer;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(PriorityPoint other) {
|
||||
double d = priority - other.priority;
|
||||
return d < 0 ? -1 : d > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + "[layer " + layer + ", (" + x + ", " + y + ")]";
|
||||
}
|
||||
}
|
23
src/deepZoom/schedulers/PythagorasScheduler.java
Normal file
23
src/deepZoom/schedulers/PythagorasScheduler.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/03
|
||||
*/
|
||||
public class PythagorasScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
|
||||
add(new PriorityPoint(i, x, y, x & y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
src/deepZoom/schedulers/RadialScheduler.java
Normal file
26
src/deepZoom/schedulers/RadialScheduler.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/17
|
||||
*/
|
||||
public class RadialScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
double dy = y - (height - 0.875) * 0.5;
|
||||
dy *= dy;
|
||||
for (int x = 0; x < width; x++) {
|
||||
double dx = x - (width - 0.75) * 0.5;
|
||||
|
||||
add(new PriorityPoint(i, x, y, dx * dx + dy));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
src/deepZoom/schedulers/RandomScheduler.java
Normal file
45
src/deepZoom/schedulers/RandomScheduler.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
import digisoft.custom.NumberFunctions;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/02
|
||||
*/
|
||||
public class RandomScheduler extends Scheduler {
|
||||
|
||||
private int area = -1;
|
||||
private double[] order;
|
||||
private int position = 0;
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
if (area != width * height) {
|
||||
area = width * height;
|
||||
|
||||
order = new double[area];
|
||||
for (int i = 0; i < area; i++) {
|
||||
order[i] = NumberFunctions.RND.nextDouble();
|
||||
}
|
||||
}
|
||||
|
||||
super.clear();
|
||||
|
||||
int p = position;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
add(new PriorityPoint(i, x, y, order[p]));
|
||||
}
|
||||
p = (p + 1) % area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PriorityPoint poll() {
|
||||
position = (position + area - 1) % area;
|
||||
return super.poll();
|
||||
}
|
||||
}
|
43
src/deepZoom/schedulers/Scheduler.java
Normal file
43
src/deepZoom/schedulers/Scheduler.java
Normal file
|
@ -0,0 +1,43 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
|
||||
import deepZoom.viewports.Viewport;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/17
|
||||
*/
|
||||
public abstract class Scheduler extends PriorityBlockingQueue<PriorityPoint> {
|
||||
|
||||
protected int numLayers = 1;
|
||||
protected int width;
|
||||
protected int height;
|
||||
private int total;
|
||||
private Viewport viewport;
|
||||
|
||||
public void setNumLayers(int numLayers) {
|
||||
this.numLayers = numLayers;
|
||||
}
|
||||
|
||||
public void setViewport(Viewport viewport) {
|
||||
this.viewport = viewport;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
width = viewport.width;
|
||||
height = viewport.height;
|
||||
|
||||
initImpl();
|
||||
|
||||
total = super.size();
|
||||
}
|
||||
|
||||
protected abstract void initImpl();
|
||||
|
||||
public double getProgress() {
|
||||
return (total - super.size()) / (double) total;
|
||||
}
|
||||
}
|
23
src/deepZoom/schedulers/SimpleScheduler.java
Normal file
23
src/deepZoom/schedulers/SimpleScheduler.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/03
|
||||
*/
|
||||
public class SimpleScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int dy = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
add(new PriorityPoint(i, x, y, dy + x));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
src/deepZoom/schedulers/SpiralScheduler.java
Normal file
33
src/deepZoom/schedulers/SpiralScheduler.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/02
|
||||
*/
|
||||
public class SpiralScheduler extends Scheduler {
|
||||
|
||||
private double thickness;
|
||||
|
||||
public SpiralScheduler(double thickness) {
|
||||
this.thickness = thickness;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
double dy = y - (height - 0.875) * 0.5;
|
||||
for (int x = 0; x < width; x++) {
|
||||
double dx = x - (width - 0.75) * 0.5;
|
||||
|
||||
double a = StrictMath.atan2(dy, -dx) / (2 * StrictMath.PI);
|
||||
dx = (int) (a + StrictMath.sqrt(dx * dx + dy * dy) / thickness) * thickness - a;
|
||||
add(new PriorityPoint(i, x, y, dx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
src/deepZoom/schedulers/SplitScheduler.java
Normal file
23
src/deepZoom/schedulers/SplitScheduler.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/03
|
||||
*/
|
||||
public class SplitScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int dy = StrictMath.abs(y - (height >> 1)) * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
add(new PriorityPoint(i, x, y, dy + x));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
37
src/deepZoom/schedulers/SquareSpiralScheduler.java
Normal file
37
src/deepZoom/schedulers/SquareSpiralScheduler.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/04
|
||||
*/
|
||||
public class SquareSpiralScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int dy = y - (height >> 1);
|
||||
for (int x = 0; x < width; x++) {
|
||||
int dx = x - (width >> 1);
|
||||
|
||||
if (dx > dy) {
|
||||
if (dx < -dy) {
|
||||
dx = 4 * dy * dy + 7 * dy + 3 + dx;
|
||||
} else {
|
||||
dx = 4 * dx * dx + 3 * dx + 1 + dy;
|
||||
}
|
||||
} else if (dx < -dy) {
|
||||
dx = 4 * dx * dx + 1 * dx - 1 - dy;
|
||||
} else {
|
||||
dx = 4 * dy * dy + 5 * dy + 1 - dx;
|
||||
}
|
||||
|
||||
add(new PriorityPoint(i, x, y, dx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
src/deepZoom/schedulers/XorScheduler.java
Normal file
25
src/deepZoom/schedulers/XorScheduler.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package deepZoom.schedulers;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/05/03
|
||||
*/
|
||||
public class XorScheduler extends Scheduler {
|
||||
|
||||
@Override
|
||||
protected void initImpl() {
|
||||
super.clear();
|
||||
|
||||
for (int i = 0; i < numLayers; i++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int dy = StrictMath.abs(y - (height >> 1));
|
||||
for (int x = 0; x < width; x++) {
|
||||
int dx = StrictMath.abs(x - (width >> 1));
|
||||
|
||||
add(new PriorityPoint(i, x, y, dx ^ dy));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
73
src/deepZoom/viewports/Viewport.java
Normal file
73
src/deepZoom/viewports/Viewport.java
Normal file
|
@ -0,0 +1,73 @@
|
|||
package deepZoom.viewports;
|
||||
|
||||
import deepZoom.parameters.Parameters;
|
||||
import deepZoom.renderer.PointInfo;
|
||||
|
||||
import digisoft.custom.util.geom.DoubleDouble;
|
||||
|
||||
/**
|
||||
* Mapping from (sub)pixel coordinates to coordinates in the complex plane.
|
||||
* Don't forget to call init() after changing the input or output configuration.
|
||||
*
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/19
|
||||
*/
|
||||
public class Viewport {
|
||||
// Input configuration.
|
||||
|
||||
public int width;
|
||||
public int height;
|
||||
// Output configuration.
|
||||
private Parameters parameters;
|
||||
// Internally used values.
|
||||
private transient DoubleDouble x0d = new DoubleDouble(0);
|
||||
private transient DoubleDouble x2 = new DoubleDouble(0);
|
||||
private transient DoubleDouble y1d = new DoubleDouble(0);
|
||||
private transient DoubleDouble y2 = new DoubleDouble(0);
|
||||
|
||||
public void setSize(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setParameters(Parameters parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
/** Call each time the viewport or parameters change. */
|
||||
public void initParameters() {
|
||||
x0d.set(4, 0);
|
||||
x0d.divSelf(parameters.getMagn());
|
||||
x0d.divSelf(width);
|
||||
|
||||
x2.set(-2 / parameters.getMagn(), 0);
|
||||
x2.addSelf(parameters.getCenterX());
|
||||
|
||||
y1d.set(-4, 0);
|
||||
y1d.divSelf(parameters.getMagn());
|
||||
y1d.divSelf(width);
|
||||
|
||||
y2.set(2 / parameters.getMagn() * height / width, 0);
|
||||
y2.addSelf(parameters.getCenterY());
|
||||
}
|
||||
|
||||
public DoubleDouble getPX(double x, double y) {
|
||||
DoubleDouble px = new DoubleDouble(x);
|
||||
px.mulSelf(x0d);
|
||||
px.addSelf(x2);
|
||||
return px;
|
||||
}
|
||||
|
||||
public DoubleDouble getPY(double x, double y) {
|
||||
DoubleDouble py = new DoubleDouble(y);
|
||||
py.mulSelf(y1d);
|
||||
py.addSelf(y2);
|
||||
return py;
|
||||
}
|
||||
|
||||
public void getPoint(double x, double y, PointInfo pointInfo) {
|
||||
pointInfo.px = getPX(x, y);
|
||||
pointInfo.py = getPY(x, y);
|
||||
}
|
||||
}
|
224
src/digisoft/custom/NumberFunctions.java
Normal file
224
src/digisoft/custom/NumberFunctions.java
Normal file
|
@ -0,0 +1,224 @@
|
|||
package digisoft.custom;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2007/11/16
|
||||
*/
|
||||
public class NumberFunctions {
|
||||
|
||||
private static final String ZEROES = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
private static SecureRandom secureRnd = null;
|
||||
public static final Random RND = new Random();
|
||||
public static final DecimalFormat COMMA_NUMBER = new DecimalFormat("#,###");
|
||||
|
||||
public static String toStringFixedLength(int i, int len) {
|
||||
String out = Integer.toString(i);
|
||||
return NumberFunctions.ZEROES.substring(out.length(), len) + out;
|
||||
}
|
||||
|
||||
public static String toStringFixedLength(long i, int len) {
|
||||
String out = Long.toString(i);
|
||||
return NumberFunctions.ZEROES.substring(out.length(), len) + out;
|
||||
}
|
||||
|
||||
public static String toStringFixedLength(int i, int base, int len) {
|
||||
String out = Long.toString(i & 0xFFFFFFFFL, base);
|
||||
|
||||
if (base > 10) {
|
||||
return NumberFunctions.ZEROES.substring(out.length(), len) + out.toUpperCase();
|
||||
}
|
||||
return NumberFunctions.ZEROES.substring(out.length(), len) + out;
|
||||
}
|
||||
|
||||
public static String toStringFixedLength(long i, int base, int len) {
|
||||
String out = Long.toString(i, base);
|
||||
|
||||
if (base > 10) {
|
||||
return NumberFunctions.ZEROES.substring(out.length(), len) + out.toUpperCase();
|
||||
}
|
||||
return NumberFunctions.ZEROES.substring(out.length(), len) + out;
|
||||
}
|
||||
|
||||
public static Random getSecureRandom() {
|
||||
if (NumberFunctions.secureRnd == null) {
|
||||
NumberFunctions.secureRnd = new SecureRandom();
|
||||
}
|
||||
return NumberFunctions.secureRnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find primes by recording a list with some proven non-prime numbers
|
||||
* (NPNs). If the NPNs are chosen carefully, the gaps between the non-prime
|
||||
* numbers will be prime numbers. <br>
|
||||
* The NPNs are chosen by calculating rectangles with an area which is an
|
||||
* odd number. The length is stepped through every odd number in the range [
|
||||
* <tt>3</tt>, <tt>sqrt(guess)</tt>]. For every length, the height is
|
||||
* stepped through such numbers (also odd numbers) so the area will stay
|
||||
* within the range [<tt>guess-gapSize</tt>, <tt>guess</tt>). When the
|
||||
* largest gap between any two successive successive prime numbers p1 and p2
|
||||
* (gap=|p2-p1|) lower than <tt>guess</tt> is smaller or equal to
|
||||
* <tt>gapSize</tt>, the result will be a prime number deterministically.<br>
|
||||
* <br>
|
||||
* Warning: Do not use this routine as-is for finding a random prime number
|
||||
* p<sup>n</sup> for any guess with equal distribution of n. The difference
|
||||
* in gaps between successive prime numbers causes the distribution to bias
|
||||
* greatly. Use <tt>findRandomPrime</tt> instead.
|
||||
*
|
||||
* @param guess
|
||||
* an initial guess
|
||||
* @return the largest prime smaller than or equal to guess
|
||||
* @since 1.0
|
||||
* @see NumberFunctions#findRandomPrime(int, int)
|
||||
* @see http://www.trnicely.net/
|
||||
*/
|
||||
public static int findPrimeNear(int guess) {
|
||||
// Make it an odd number.
|
||||
if ((guess & 1) == 0) {
|
||||
guess--;
|
||||
}
|
||||
|
||||
// Find largest gap
|
||||
int maxGap;
|
||||
if (guess <= 523) {
|
||||
// Minimum gap for <7 bits. (closest was 9.030667136 bits)
|
||||
maxGap = 14;
|
||||
} else if (guess <= 155921) {
|
||||
// Minimum gap for <15 bits. (closest was 17.25045573 bits)
|
||||
maxGap = 72;
|
||||
} else if (guess <= 2147437599) // Magic number? see else block.
|
||||
{
|
||||
// Minimum gap for <31 bits. (closest was 31.09957781 bits)
|
||||
maxGap = 292;
|
||||
} else {
|
||||
throw new IllegalArgumentException("guess+floor(sqrt(guess))-292 should be below 2^31-1, so guess should be below 2147437600");
|
||||
}
|
||||
int halfGap = maxGap >> 1;
|
||||
|
||||
// The list is compressed and reversed. (ie. index 0 is the guess, 1 is
|
||||
// guess-2, etc.)
|
||||
boolean[] primes = new boolean[halfGap];
|
||||
Arrays.fill(primes, true);
|
||||
|
||||
int halfway = (int) StrictMath.sqrt(guess);
|
||||
int minGap = guess - maxGap;
|
||||
|
||||
// fill the array with nonprimes
|
||||
for (int i = 3; i <= halfway; i += 2) {
|
||||
int max = guess / i;
|
||||
int min = (minGap + i) / i;
|
||||
if ((min & 1) == 0) {
|
||||
min++;
|
||||
}
|
||||
for (int j = min; j <= max; j += 2) {
|
||||
int nonPrime = j * i;
|
||||
int index = guess - nonPrime >> 1;
|
||||
if (index >= 0) {
|
||||
primes[index] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the highest prime number in the list.
|
||||
for (int a = 0; a < halfGap; a++) {
|
||||
if (primes[a]) {
|
||||
return guess - (a << 1);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("gap too small");
|
||||
}
|
||||
|
||||
/**
|
||||
* Find primes by recording a list with some proven non-prime numbers
|
||||
* (NPNs). If the NPNs are chosen carefully, the gaps between the non-prime
|
||||
* numbers will be prime numbers. <br>
|
||||
* The NPNs are chosen by calculating rectangles with an area which is an
|
||||
* odd number. The length is stepped through every odd number in the range [
|
||||
* <tt>3</tt>, <tt>sqrt(guess)</tt>]. For every length, the height is
|
||||
* stepped through such numbers (also odd numbers) so the area will stay
|
||||
* within the range [<tt>guess-gapSize</tt>, <tt>guess</tt>). When the
|
||||
* largest gap between any two successive successive prime numbers p1 and p2
|
||||
* (gap=|p2-p1|) lower than <tt>guess</tt> is smaller or equal to
|
||||
* <tt>gapSize</tt>, the result will be a prime number deterministically.<br>
|
||||
* <br>
|
||||
* Warning: Do not use this routine as-is for finding a random prime number
|
||||
* p<sup>n</sup> for any guess with equal distribution of n. The difference
|
||||
* in gaps between successive prime numbers causes the distribution to bias
|
||||
* greatly. Use <tt>findRandomPrime</tt> instead.
|
||||
*
|
||||
* @param guess
|
||||
* an initial guess
|
||||
* @return the largest prime smaller than or equal to guess
|
||||
* @since 1.0
|
||||
* @see NumberFunctions#findRandomPrime(int, int)
|
||||
* @see http://www.trnicely.net/
|
||||
*/
|
||||
public static long findPrimeNear(long guess) {
|
||||
// Make it an odd number.
|
||||
if ((guess & 1) == 0) {
|
||||
guess--;
|
||||
}
|
||||
|
||||
// Find largest gap
|
||||
int maxGap;
|
||||
if (guess <= 2147437600) {// Delegate to a faster function.
|
||||
return NumberFunctions.findPrimeNear((int) guess);
|
||||
} else if (guess <= 2300942549L) {
|
||||
// Minimum gap for <31 bits. (closest was 31.10 bits)
|
||||
maxGap = 292;
|
||||
} else if (guess <= 9223372033817776756L) // Magic number? see else block.
|
||||
{
|
||||
// There is known gap yet for <63 bits, so I'm using the next known
|
||||
// gap (85.90 bits)
|
||||
maxGap = 1448;
|
||||
} else {
|
||||
throw new IllegalArgumentException("guess+floor(sqrt(guess))-1448 should be below 2^63-1, so guess should be below 9223372033817776757");
|
||||
}
|
||||
int halfGap = maxGap >> 1;
|
||||
|
||||
// The list is compressed and reversed. (ie. index 0 is the guess, 1 is
|
||||
// guess-2, etc.)
|
||||
boolean[] primes = new boolean[halfGap];
|
||||
Arrays.fill(primes, true);
|
||||
|
||||
long halfway = (long) StrictMath.sqrt(guess);
|
||||
long minGap = guess - maxGap;
|
||||
|
||||
// fill the array with nonprimes
|
||||
for (long i = 3; i <= halfway; i += 2) {
|
||||
long max = guess / i;
|
||||
long min = (minGap + i) / i;
|
||||
if ((min & 1) == 0) {
|
||||
min++;
|
||||
}
|
||||
for (long j = min; j <= max; j += 2) {
|
||||
long nonPrime = j * i;
|
||||
int index = (int) (guess - nonPrime) >> 1;
|
||||
if (index >= 0) {
|
||||
primes[index] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the highest prime number in the list.
|
||||
for (int a = 0; a < halfGap; a++) {
|
||||
if (primes[a]) {
|
||||
return guess - (a << 1);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("gap too small");
|
||||
}
|
||||
|
||||
public static int factorial(int v) {
|
||||
int out = 1;
|
||||
for (int i = 2; i <= v; i++) {
|
||||
out *= i;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
534
src/digisoft/custom/awt/Color3f.java
Normal file
534
src/digisoft/custom/awt/Color3f.java
Normal file
|
@ -0,0 +1,534 @@
|
|||
package digisoft.custom.awt;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2005/10/03
|
||||
*/
|
||||
public class Color3f {
|
||||
|
||||
private static final float MIN_CLIP_LEVEL = -0.003921568627450980392156862745098f;
|
||||
private static final float MAX_CLIP_LEVEL = 1.003921568627450980392156862745098f;
|
||||
public float r;
|
||||
public float g;
|
||||
public float b;
|
||||
|
||||
/**
|
||||
* Create the color opaque black
|
||||
*/
|
||||
public Color3f() {
|
||||
this(0f, 0f, 0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an opaque color from packed RGB triple
|
||||
*
|
||||
* @param i
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f(int i) {
|
||||
b = (i & 0xFF) / 255f;
|
||||
g = ((i >>= 8) & 0xFF) / 255f;
|
||||
r = (i >> 8 & 0xFF) / 255f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an opaque color defined gray shade
|
||||
*
|
||||
* @param i
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f(float i) {
|
||||
this(i, i, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an opaque defined color
|
||||
*
|
||||
* @param r
|
||||
* @param g
|
||||
* @param b
|
||||
*/
|
||||
public Color3f(float r, float g, float b) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an opaque defined color
|
||||
*
|
||||
* @param r
|
||||
* @param g
|
||||
* @param b
|
||||
*/
|
||||
public Color3f(int r, int g, int b) {
|
||||
this.r = r / 255f;
|
||||
this.g = g / 255f;
|
||||
this.b = b / 255f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param color
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f(Color color) {
|
||||
r = color.getRed() / 255f;
|
||||
g = color.getGreen() / 255f;
|
||||
b = color.getBlue() / 255f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param color
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f(Color3f color) {
|
||||
r = color.r;
|
||||
g = color.g;
|
||||
b = color.b;
|
||||
}
|
||||
|
||||
public void set(Color3f c) {
|
||||
r = c.r;
|
||||
g = c.g;
|
||||
b = c.b;
|
||||
}
|
||||
|
||||
public void set(int r, int g, int b) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public float getGrayValue() {
|
||||
return 0.299f * r + 0.587f * g + 0.114f * b;
|
||||
}
|
||||
|
||||
public void addSelf(int i) {
|
||||
b += (i & 0xFF) / 255f;
|
||||
g += ((i >>= 8) & 0xFF) / 255f;
|
||||
r += (i >> 8 & 0xFF) / 255f;
|
||||
}
|
||||
|
||||
public Color3f scale(float f) {
|
||||
return new Color3f(r * f, g * f, b * f);
|
||||
}
|
||||
|
||||
public void scaleSelf(float f) {
|
||||
r *= f;
|
||||
g *= f;
|
||||
b *= f;
|
||||
}
|
||||
|
||||
public Color3f interpolateLinear(Color3f c, float f) {
|
||||
return new Color3f( //
|
||||
r + (c.r - r) * f, //
|
||||
g + (c.g - g) * f, //
|
||||
b + (c.b - b) * f);
|
||||
}
|
||||
|
||||
public void interpolateLinearSelf(Color3f c, float f) {
|
||||
r = r + (c.r - r) * f;
|
||||
g = g + (c.g - g) * f;
|
||||
b = b + (c.b - b) * f;
|
||||
}
|
||||
|
||||
public Color3f gamma(float gammaFactor) {
|
||||
return new Color3f( //
|
||||
(float) Math.pow(r, gammaFactor), //
|
||||
(float) Math.pow(g, gammaFactor), //
|
||||
(float) Math.pow(b, gammaFactor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the components of this color, as specified by the HSB model, to
|
||||
* an equivalent set of values for the default RGB model.
|
||||
* <p>
|
||||
* The <code>saturation</code> and <code>brightness</code> components should
|
||||
* be floating-point values between zero and one (numbers in the range
|
||||
* 0.0-1.0). The <code>hue</code> component can be any floating-point
|
||||
* number. The floor of this number is subtracted from it to create a
|
||||
* fraction between 0 and 1. This fractional number is then virtually
|
||||
* multiplied by 360 to produce the hue angle in the HSB color model.
|
||||
* <p>
|
||||
*
|
||||
* @param hsb
|
||||
* the Color3f containing the components hue, saturation,
|
||||
* brightness and alpha in the fields of red, green, blue and
|
||||
* alpha, respectively
|
||||
* @return the Color3f with the RGB value of the color with the indicated
|
||||
* hue, saturation, brightness and alpha.
|
||||
*
|
||||
* @see java.awt.Color#HSB2RGB(float, float, float)
|
||||
* @see java.awt.Color#getRGB()
|
||||
* @see java.awt.Color#Color(int)
|
||||
* @see java.awt.image.ColorModel#getRGBdefault()
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f hsb2Rgb() {
|
||||
if (g == 0) {
|
||||
return new Color3f(b, b, b);
|
||||
}
|
||||
Color3f out = new Color3f(0, 0, 0);
|
||||
float hue6 = (r - (float) Math.floor(r)) * 6;
|
||||
float hue_f = hue6 - (float) java.lang.Math.floor(hue6);
|
||||
float p = b * (1 - g);
|
||||
switch ((int) hue6) {
|
||||
case 0:
|
||||
case 6: {
|
||||
out.r = b;
|
||||
out.g = b * (1 - g * (1 - hue_f));
|
||||
out.b = p;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
out.r = b * (1 - g * hue_f);
|
||||
out.g = b;
|
||||
out.b = p;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
out.r = p;
|
||||
out.g = b;
|
||||
out.b = b * (1 - g * (1 - hue_f));
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
out.r = p;
|
||||
out.g = b * (1 - g * hue_f);
|
||||
out.b = b;
|
||||
}
|
||||
break;
|
||||
case 4: {
|
||||
out.r = b * (1 - g * (1 - hue_f));
|
||||
out.g = p;
|
||||
out.b = b;
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
out.r = b;
|
||||
out.g = p;
|
||||
out.b = b * (1 - g * hue_f);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the components of this color, as specified by the default RGB
|
||||
* model, to an equivalent set of values for hue, saturation, and brightness
|
||||
* that are the three components of the HSB model.
|
||||
*
|
||||
* @see java.awt.Color#RGB2HSB(int, int, int, float[])
|
||||
* @see java.awt.Color#getRGB()
|
||||
* @see java.awt.Color#Color(int)
|
||||
* @see java.awt.image.ColorModel#getRGBdefault()
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public Color3f rgb2Hsb() {
|
||||
float cmax = r > g ? r : g;
|
||||
if (b > cmax) {
|
||||
cmax = b;
|
||||
}
|
||||
float cmin = r < g ? r : g;
|
||||
if (b < cmin) {
|
||||
cmin = b;
|
||||
}
|
||||
float dist = cmax - cmin;
|
||||
|
||||
Color3f out = new Color3f(0f, 0f, 0f);
|
||||
|
||||
out.b = cmax;
|
||||
out.g = cmax != 0 ? dist / cmax : 0;
|
||||
|
||||
if (out.g == 0) {
|
||||
out.r = 0;
|
||||
} else {
|
||||
if (r == cmax) {
|
||||
if (g >= b) {
|
||||
out.r = (g - b) / dist;
|
||||
} else {
|
||||
out.r = 6.0f + (g - b) / dist;
|
||||
}
|
||||
} else if (g == cmax) {
|
||||
out.r = 2.0f + (b - r) / dist;
|
||||
} else {
|
||||
out.r = 4.0f + (r - g) / dist;
|
||||
}
|
||||
out.r /= 6.0f;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the components of this color, as specified by the default RGB
|
||||
* model, to an equivalent set of values for hue, saturation, and brightness
|
||||
* that are the three components of the HSB model.
|
||||
*
|
||||
* @see java.awt.Color#RGB2HSB(int, int, int, float[])
|
||||
* @see java.awt.Color#getRGB()
|
||||
* @see java.awt.Color#Color(int)
|
||||
* @see java.awt.image.ColorModel#getRGBdefault()
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public void rgb2HsbSelf() {
|
||||
float cmax = r > g ? r : g;
|
||||
if (b > cmax) {
|
||||
cmax = b;
|
||||
}
|
||||
float cmin = r < g ? r : g;
|
||||
if (b < cmin) {
|
||||
cmin = b;
|
||||
}
|
||||
float dist = cmax - cmin;
|
||||
|
||||
float g = cmax != 0 ? dist / cmax : 0;
|
||||
|
||||
if (g == 0) {
|
||||
r = 0;
|
||||
} else {
|
||||
if (r == cmax) {
|
||||
if (this.g >= b) {
|
||||
r = (this.g - b) / dist;
|
||||
} else {
|
||||
r = 6.0f + (this.g - b) / dist;
|
||||
}
|
||||
} else if (this.g == cmax) {
|
||||
r = 2.0f + (b - r) / dist;
|
||||
} else {
|
||||
r = 4.0f + (r - this.g) / dist;
|
||||
}
|
||||
r /= 6.0f;
|
||||
}
|
||||
b = cmax;
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RGB to YPbPr (the floating point version of YCbCr).
|
||||
*
|
||||
* @return R=Y in [0, 1]; G=Pb in [-0.5 0.5]; B=Pr in [-0.5 0.5]
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f rgb2YPbPr() {
|
||||
return new Color3f( //
|
||||
+0.29900000000000000000f * r + 0.58700000000000000000f * g + 0.114000000000000000000f * b, //
|
||||
-0.16873589164785553047f * r - 0.33126410835214446952f * g + 0.500000000000000000000f * b, //
|
||||
+0.50000000000000000000f * r - 0.41868758915834522111f * g - 0.081312410841654778888f * b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RGB to YPbPr (the floating point version of YCbCr).
|
||||
*
|
||||
* @return R=Y in [0, 1]; G=Pb in [-0.5 0.5]; B=Pr in [-0.5 0.5]
|
||||
* @since 1.0
|
||||
*/
|
||||
public void rgb2YPbPrSelf() {
|
||||
float r = +0.29900000000000000000f * this.r + 0.58700000000000000000f * g + 0.114000000000000000000f * b;
|
||||
float g = -0.16873589164785553047f * this.r - 0.33126410835214446952f * this.g + 0.500000000000000000000f * b;
|
||||
b = +0.50000000000000000000f * this.r - 0.41868758915834522111f * this.g - 0.081312410841654778888f * b;
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert YPbPr (the floating point version of YCbCr) to RGB. Inputs: R=Y
|
||||
* in [0 1]; G=Pb in [-0.5 0.5]; B=Pr in [-0.5 0.5]
|
||||
*
|
||||
* @return RGB colors
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f tPbPr2Rgb() {
|
||||
return new Color3f( //
|
||||
r /* ***************************** */ + 1.40200000000000000000f * b, //
|
||||
r - 0.34413628620102214650f * g - 0.71413628620102214645f * b, //
|
||||
r + 1.77200000000000000000f * g /*
|
||||
* **********************
|
||||
* ******
|
||||
*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RGB to YUV (the colorspace used by PAL TV).
|
||||
*
|
||||
* @return R=Y in [0, 1]; G=U in [-0.5 0.5]; B=V in [-0.5 0.5]
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f rgb2Yuv() {
|
||||
return new Color3f( //
|
||||
+0.29900000000000000000f * r + 0.58700000000000000000f * g + 0.11400000000000000000f * b, //
|
||||
-0.14713769751693002257f * r - 0.28886230248306997742f * g + 0.43600000000000000000f * b, //
|
||||
+0.61500000000000000000f * r - 0.51498573466476462197f * g - 0.10001426533523537803f * b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert YUV (the colorspace used in PAL TV) to RGB. Inputs: R=Y in [0 1];
|
||||
* G=U in [-0.5 0.5]; B=V in [-0.5 0.5]
|
||||
*
|
||||
* @return RGB colors
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f yuv2Rgb() {
|
||||
return new Color3f( //
|
||||
r /* ***************************** */ + 1.13983739837398373980f * b, //
|
||||
r - 0.39465170435897035149f * g - 0.58059860666749768007f * b, //
|
||||
r + 2.03211009174311926600f * g /*
|
||||
* **********************
|
||||
* ******
|
||||
*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RGB to YUV (the colorspace used by PAL TV).
|
||||
*
|
||||
* @return R=Y in [0, 1]; G=U in [-0.5 0.5]; B=V in [-0.5 0.5]
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f rgb2YiQ() {
|
||||
return new Color3f( //
|
||||
+0.29900000000000000000f * r + 0.58700000000000000000f * g + 0.11400000000000000000f * b, //
|
||||
+0.59571613491277455268f * r - 0.27445283783925646357f * g - 0.32126329707351808911f * b, //
|
||||
+0.21145640212011786639f * r - 0.52259104529161116836f * g + 0.31113464317149330198f * b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert YIQ (the colorspace used in NTSC TV) to RGB. Inputs: R=Y in [0
|
||||
* 1]; G=I in [-0.5 0.5]; B=Q in [-0.5 0.5]
|
||||
*
|
||||
* @return RGB colors
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f yiq2Rgb() {
|
||||
return new Color3f( //
|
||||
r + 0.95629483232089399045f * g + 0.62102512544472871408f * b, //
|
||||
r - 0.27212147408397731948f * g - 0.64738095351761572226f * b, //
|
||||
r - 1.10698990856712821590f * g + 1.70461497549882932850f * b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert RGB to XYZ (the CIE 1931 color space).
|
||||
*
|
||||
* @return R=Y in [0, 1]; G=U in [0 1]; B=V in [0 1]
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f rgb2Xyz() {
|
||||
return new Color3f( //
|
||||
+0.43030294260923249074f * r + 0.34163640134469669562f * g + 0.17822777850125160973f * b, //
|
||||
+0.22187495478288550304f * r + 0.70683393381661385301f * g + 0.071291111400500643890f * b, //
|
||||
+0.020170450434807773004f * r + 0.12958622119971253972f * g + 0.93866630010659181124f * b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert XYZ (the CIE 1931 color space) to RGB. Inputs: R=X in [0 1]; G=Y
|
||||
* in [0 1]; B=z in [0 1]
|
||||
*
|
||||
* @return RGB colors
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color3f xyz2Rgb() {
|
||||
return new Color3f( //
|
||||
+2.0608465608465608465f * r - 0.93738977072310405639f * g - 0.32010582010582010580f * b, //
|
||||
-1.1415343915343915346f * r + 2.2094356261022927693f * g + 0.048941798941798941806f * b, //
|
||||
+0.080687830687830687828f * r - 0.27204585537918871252f * g + 1.2711640211640211641f * b);
|
||||
}
|
||||
|
||||
public Color3f clip() {
|
||||
float ra = r;
|
||||
float ga = g;
|
||||
float ba = b;
|
||||
|
||||
if (ra < 0) {
|
||||
ra = 0;
|
||||
} else if (ra > 1) {
|
||||
ra = 1;
|
||||
}
|
||||
if (ga < 0) {
|
||||
ga = 0;
|
||||
} else if (ga > 1) {
|
||||
ga = 1;
|
||||
}
|
||||
if (ba < 0) {
|
||||
ba = 0;
|
||||
} else if (ba > 1) {
|
||||
ba = 1;
|
||||
}
|
||||
|
||||
return new Color3f(ra, ga, ba);
|
||||
}
|
||||
|
||||
public Color3f showClip() {
|
||||
if (r < Color3f.MIN_CLIP_LEVEL || r > Color3f.MAX_CLIP_LEVEL || g < Color3f.MIN_CLIP_LEVEL || g > Color3f.MAX_CLIP_LEVEL || b < Color3f.MIN_CLIP_LEVEL
|
||||
|| b > Color3f.MAX_CLIP_LEVEL) {
|
||||
return new Color3f(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isClipping() {
|
||||
return r < Color3f.MIN_CLIP_LEVEL || r > Color3f.MAX_CLIP_LEVEL || g < Color3f.MIN_CLIP_LEVEL || g > Color3f.MAX_CLIP_LEVEL
|
||||
|| b < Color3f.MIN_CLIP_LEVEL || b > Color3f.MAX_CLIP_LEVEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this color to a color understood by the java.awt package.
|
||||
*
|
||||
* @return an instance of java.awt.Color with the color attributes clamped
|
||||
* to {black,white}
|
||||
* @see java.awt.Color
|
||||
* @since 1.0
|
||||
*/
|
||||
public Color toColor() {
|
||||
float ra = r;
|
||||
float ga = g;
|
||||
float ba = b;
|
||||
|
||||
if (ra < 0) {
|
||||
ra = 0;
|
||||
} else if (ra > 1) {
|
||||
ra = 1;
|
||||
}
|
||||
if (ga < 0) {
|
||||
ga = 0;
|
||||
} else if (ga > 1) {
|
||||
ga = 1;
|
||||
}
|
||||
if (ba < 0) {
|
||||
ba = 0;
|
||||
} else if (ba > 1) {
|
||||
ba = 1;
|
||||
}
|
||||
|
||||
return new java.awt.Color(ra, ga, ba);
|
||||
}
|
||||
|
||||
public int getRGB() {
|
||||
int ra = (int) (r * 255 + 0.5);
|
||||
int ga = (int) (g * 255 + 0.5);
|
||||
int ba = (int) (b * 255 + 0.5);
|
||||
|
||||
if (ra < 0) {
|
||||
ra = 0;
|
||||
} else if (ra > 255) {
|
||||
ra = 255;
|
||||
}
|
||||
if (ga < 0) {
|
||||
ga = 0;
|
||||
} else if (ga > 255) {
|
||||
ga = 255;
|
||||
}
|
||||
if (ba < 0) {
|
||||
ba = 0;
|
||||
} else if (ba > 255) {
|
||||
ba = 255;
|
||||
}
|
||||
|
||||
return ba + (ga + (ra << 8) << 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.getClass().getSimpleName() + "[" + r + ", " + g + ", " + b + "]";
|
||||
}
|
||||
}
|
184
src/digisoft/custom/awt/Color3fConst.java
Normal file
184
src/digisoft/custom/awt/Color3fConst.java
Normal file
|
@ -0,0 +1,184 @@
|
|||
package digisoft.custom.awt;
|
||||
|
||||
import digisoft.custom.NumberFunctions;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/16
|
||||
*/
|
||||
public class Color3fConst {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int p = 0;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
Color3f c = new Color3f(Color3fConst.DOS_PALETTE[p++]);
|
||||
System.out.print("0x" + NumberFunctions.toStringFixedLength(c.getRGB(), 16, 6) + ", ");
|
||||
}
|
||||
System.out.println(" //");
|
||||
}
|
||||
}
|
||||
public static final int[] DOS_PALETTE = {0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA, //
|
||||
0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF, //
|
||||
0x000000, 0x141414, 0x202020, 0x2C2C2C, 0x383838, 0x454545, 0x515151, 0x616161, //
|
||||
0x717171, 0x828282, 0x929292, 0xA2A2A2, 0xB6B6B6, 0xCBCBCB, 0xE3E3E3, 0xFFFFFF, //
|
||||
0x0000FF, 0x4100FF, 0x7D00FF, 0xBE00FF, 0xFF00FF, 0xFF00BE, 0xFF007D, 0xFF0041, //
|
||||
0xFF0000, 0xFF4100, 0xFF7D00, 0xFFBE00, 0xFFFF00, 0xBEFF00, 0x7DFF00, 0x41FF00, //
|
||||
0x00FF00, 0x00FF41, 0x00FF7D, 0x00FFBE, 0x00FFFF, 0x00BEFF, 0x007DFF, 0x0041FF, //
|
||||
0x7D7DFF, 0x9E7DFF, 0xBE7DFF, 0xDF7DFF, 0xFF7DFF, 0xFF7DDF, 0xFF7DBE, 0xFF7D9E, //
|
||||
0xFF7D7D, 0xFF9E7D, 0xFFBE7D, 0xFFDF7D, 0xFFFF7D, 0xDFFF7D, 0xBEFF7D, 0x9EFF7D, //
|
||||
0x7DFF7D, 0x7DFF9E, 0x7DFFBE, 0x7DFFDF, 0x7DFFFF, 0x7DDFFF, 0x7DBEFF, 0x7D9EFF, //
|
||||
0xB6B6FF, 0xC7B6FF, 0xDBB6FF, 0xEBB6FF, 0xFFB6FF, 0xFFB6EB, 0xFFB6DB, 0xFFB6C7, //
|
||||
0xFFB6B6, 0xFFC7B6, 0xFFDBB6, 0xFFEBB6, 0xFFFFB6, 0xEBFFB6, 0xDBFFB6, 0xC7FFB6, //
|
||||
0xB6FFB6, 0xB6FFC7, 0xB6FFDB, 0xB6FFEB, 0xB6FFFF, 0xB6EBFF, 0xB6DBFF, 0xB6C7FF, //
|
||||
0x000071, 0x1C0071, 0x380071, 0x550071, 0x710071, 0x710055, 0x710038, 0x71001C, //
|
||||
0x710000, 0x711C00, 0x713800, 0x715500, 0x717100, 0x557100, 0x387100, 0x1C7100, //
|
||||
0x007100, 0x00711C, 0x007138, 0x007155, 0x007171, 0x005571, 0x003871, 0x001C71, //
|
||||
0x383871, 0x453871, 0x553871, 0x613871, 0x713871, 0x713861, 0x713855, 0x713845, //
|
||||
0x713838, 0x714538, 0x715538, 0x716138, 0x717138, 0x617138, 0x557138, 0x457138, //
|
||||
0x387138, 0x387145, 0x387155, 0x387161, 0x387171, 0x386171, 0x385571, 0x384571, //
|
||||
0x515171, 0x595171, 0x615171, 0x695171, 0x715171, 0x715169, 0x715161, 0x715159, //
|
||||
0x715151, 0x715951, 0x716151, 0x716951, 0x717151, 0x697151, 0x617151, 0x597151, //
|
||||
0x517151, 0x517159, 0x517161, 0x517169, 0x517171, 0x516971, 0x516171, 0x515971, //
|
||||
0x000041, 0x100041, 0x200041, 0x300041, 0x410041, 0x410030, 0x410020, 0x410010, //
|
||||
0x410000, 0x411000, 0x412000, 0x413000, 0x414100, 0x304100, 0x204100, 0x104100, //
|
||||
0x004100, 0x004110, 0x004120, 0x004130, 0x004141, 0x003041, 0x002041, 0x001041, //
|
||||
0x202041, 0x282041, 0x302041, 0x382041, 0x412041, 0x412038, 0x412030, 0x412028, //
|
||||
0x412020, 0x412820, 0x413020, 0x413820, 0x414120, 0x384120, 0x304120, 0x284120, //
|
||||
0x204120, 0x204128, 0x204130, 0x204138, 0x204141, 0x203841, 0x203041, 0x202841, //
|
||||
0x2C2C41, 0x302C41, 0x342C41, 0x3C2C41, 0x412C41, 0x412C3C, 0x412C34, 0x412C30, //
|
||||
0x412C2C, 0x41302C, 0x41342C, 0x413C2C, 0x41412C, 0x3C412C, 0x34412C, 0x30412C, //
|
||||
0x2C412C, 0x2C4130, 0x2C4134, 0x2C413C, 0x2C4141, 0x2C3C41, 0x2C3441, 0x2C3041, //
|
||||
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, //
|
||||
0x000000};
|
||||
public static final Color3f[] DOS_COLORS = {new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.0f, 0.0f, 0.6666667f), //
|
||||
new Color3f(0.0f, 0.6666667f, 0.0f), new Color3f(0.0f, 0.6666667f, 0.6666667f), //
|
||||
new Color3f(0.6666667f, 0.0f, 0.0f), new Color3f(0.6666667f, 0.0f, 0.6666667f), //
|
||||
new Color3f(0.6666667f, 0.33333334f, 0.0f), new Color3f(0.6666667f, 0.6666667f, 0.6666667f), //
|
||||
new Color3f(0.33333334f, 0.33333334f, 0.33333334f), new Color3f(0.33333334f, 0.33333334f, 1.0f), //
|
||||
new Color3f(0.33333334f, 1.0f, 0.33333334f), new Color3f(0.33333334f, 1.0f, 1.0f), //
|
||||
new Color3f(1.0f, 0.33333334f, 0.33333334f), new Color3f(1.0f, 0.33333334f, 1.0f), //
|
||||
new Color3f(1.0f, 1.0f, 0.33333334f), new Color3f(1.0f, 1.0f, 1.0f), //
|
||||
new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.078431375f, 0.078431375f, 0.078431375f), //
|
||||
new Color3f(0.1254902f, 0.1254902f, 0.1254902f), new Color3f(0.17254902f, 0.17254902f, 0.17254902f), //
|
||||
new Color3f(0.21960784f, 0.21960784f, 0.21960784f), new Color3f(0.27058825f, 0.27058825f, 0.27058825f), //
|
||||
new Color3f(0.31764707f, 0.31764707f, 0.31764707f), new Color3f(0.38039216f, 0.38039216f, 0.38039216f), //
|
||||
new Color3f(0.44313726f, 0.44313726f, 0.44313726f), new Color3f(0.50980395f, 0.50980395f, 0.50980395f), //
|
||||
new Color3f(0.57254905f, 0.57254905f, 0.57254905f), new Color3f(0.63529414f, 0.63529414f, 0.63529414f), //
|
||||
new Color3f(0.7137255f, 0.7137255f, 0.7137255f), new Color3f(0.79607844f, 0.79607844f, 0.79607844f), //
|
||||
new Color3f(0.8901961f, 0.8901961f, 0.8901961f), new Color3f(1.0f, 1.0f, 1.0f), //
|
||||
new Color3f(0.0f, 0.0f, 1.0f), new Color3f(0.25490198f, 0.0f, 1.0f), //
|
||||
new Color3f(0.49019608f, 0.0f, 1.0f), new Color3f(0.74509805f, 0.0f, 1.0f), //
|
||||
new Color3f(1.0f, 0.0f, 1.0f), new Color3f(1.0f, 0.0f, 0.74509805f), //
|
||||
new Color3f(1.0f, 0.0f, 0.49019608f), new Color3f(1.0f, 0.0f, 0.25490198f), //
|
||||
new Color3f(1.0f, 0.0f, 0.0f), new Color3f(1.0f, 0.25490198f, 0.0f), //
|
||||
new Color3f(1.0f, 0.49019608f, 0.0f), new Color3f(1.0f, 0.74509805f, 0.0f), //
|
||||
new Color3f(1.0f, 1.0f, 0.0f), new Color3f(0.74509805f, 1.0f, 0.0f), //
|
||||
new Color3f(0.49019608f, 1.0f, 0.0f), new Color3f(0.25490198f, 1.0f, 0.0f), //
|
||||
new Color3f(0.0f, 1.0f, 0.0f), new Color3f(0.0f, 1.0f, 0.25490198f), //
|
||||
new Color3f(0.0f, 1.0f, 0.49019608f), new Color3f(0.0f, 1.0f, 0.74509805f), //
|
||||
new Color3f(0.0f, 1.0f, 1.0f), new Color3f(0.0f, 0.74509805f, 1.0f), //
|
||||
new Color3f(0.0f, 0.49019608f, 1.0f), new Color3f(0.0f, 0.25490198f, 1.0f), //
|
||||
new Color3f(0.49019608f, 0.49019608f, 1.0f), new Color3f(0.61960787f, 0.49019608f, 1.0f), //
|
||||
new Color3f(0.74509805f, 0.49019608f, 1.0f), new Color3f(0.8745098f, 0.49019608f, 1.0f), //
|
||||
new Color3f(1.0f, 0.49019608f, 1.0f), new Color3f(1.0f, 0.49019608f, 0.8745098f), //
|
||||
new Color3f(1.0f, 0.49019608f, 0.74509805f), new Color3f(1.0f, 0.49019608f, 0.61960787f), //
|
||||
new Color3f(1.0f, 0.49019608f, 0.49019608f), new Color3f(1.0f, 0.61960787f, 0.49019608f), //
|
||||
new Color3f(1.0f, 0.74509805f, 0.49019608f), new Color3f(1.0f, 0.8745098f, 0.49019608f), //
|
||||
new Color3f(1.0f, 1.0f, 0.49019608f), new Color3f(0.8745098f, 1.0f, 0.49019608f), //
|
||||
new Color3f(0.74509805f, 1.0f, 0.49019608f), new Color3f(0.61960787f, 1.0f, 0.49019608f), //
|
||||
new Color3f(0.49019608f, 1.0f, 0.49019608f), new Color3f(0.49019608f, 1.0f, 0.61960787f), //
|
||||
new Color3f(0.49019608f, 1.0f, 0.74509805f), new Color3f(0.49019608f, 1.0f, 0.8745098f), //
|
||||
new Color3f(0.49019608f, 1.0f, 1.0f), new Color3f(0.49019608f, 0.8745098f, 1.0f), //
|
||||
new Color3f(0.49019608f, 0.74509805f, 1.0f), new Color3f(0.49019608f, 0.61960787f, 1.0f), //
|
||||
new Color3f(0.7137255f, 0.7137255f, 1.0f), new Color3f(0.78039217f, 0.7137255f, 1.0f), //
|
||||
new Color3f(0.85882354f, 0.7137255f, 1.0f), new Color3f(0.92156863f, 0.7137255f, 1.0f), //
|
||||
new Color3f(1.0f, 0.7137255f, 1.0f), new Color3f(1.0f, 0.7137255f, 0.92156863f), //
|
||||
new Color3f(1.0f, 0.7137255f, 0.85882354f), new Color3f(1.0f, 0.7137255f, 0.78039217f), //
|
||||
new Color3f(1.0f, 0.7137255f, 0.7137255f), new Color3f(1.0f, 0.78039217f, 0.7137255f), //
|
||||
new Color3f(1.0f, 0.85882354f, 0.7137255f), new Color3f(1.0f, 0.92156863f, 0.7137255f), //
|
||||
new Color3f(1.0f, 1.0f, 0.7137255f), new Color3f(0.92156863f, 1.0f, 0.7137255f), //
|
||||
new Color3f(0.85882354f, 1.0f, 0.7137255f), new Color3f(0.78039217f, 1.0f, 0.7137255f), //
|
||||
new Color3f(0.7137255f, 1.0f, 0.7137255f), new Color3f(0.7137255f, 1.0f, 0.78039217f), //
|
||||
new Color3f(0.7137255f, 1.0f, 0.85882354f), new Color3f(0.7137255f, 1.0f, 0.92156863f), //
|
||||
new Color3f(0.7137255f, 1.0f, 1.0f), new Color3f(0.7137255f, 0.92156863f, 1.0f), //
|
||||
new Color3f(0.7137255f, 0.85882354f, 1.0f), new Color3f(0.7137255f, 0.78039217f, 1.0f), //
|
||||
new Color3f(0.0f, 0.0f, 0.44313726f), new Color3f(0.10980392f, 0.0f, 0.44313726f), //
|
||||
new Color3f(0.21960784f, 0.0f, 0.44313726f), new Color3f(0.33333334f, 0.0f, 0.44313726f), //
|
||||
new Color3f(0.44313726f, 0.0f, 0.44313726f), new Color3f(0.44313726f, 0.0f, 0.33333334f), //
|
||||
new Color3f(0.44313726f, 0.0f, 0.21960784f), new Color3f(0.44313726f, 0.0f, 0.10980392f), //
|
||||
new Color3f(0.44313726f, 0.0f, 0.0f), new Color3f(0.44313726f, 0.10980392f, 0.0f), //
|
||||
new Color3f(0.44313726f, 0.21960784f, 0.0f), new Color3f(0.44313726f, 0.33333334f, 0.0f), //
|
||||
new Color3f(0.44313726f, 0.44313726f, 0.0f), new Color3f(0.33333334f, 0.44313726f, 0.0f), //
|
||||
new Color3f(0.21960784f, 0.44313726f, 0.0f), new Color3f(0.10980392f, 0.44313726f, 0.0f), //
|
||||
new Color3f(0.0f, 0.44313726f, 0.0f), new Color3f(0.0f, 0.44313726f, 0.10980392f), //
|
||||
new Color3f(0.0f, 0.44313726f, 0.21960784f), new Color3f(0.0f, 0.44313726f, 0.33333334f), //
|
||||
new Color3f(0.0f, 0.44313726f, 0.44313726f), new Color3f(0.0f, 0.33333334f, 0.44313726f), //
|
||||
new Color3f(0.0f, 0.21960784f, 0.44313726f), new Color3f(0.0f, 0.10980392f, 0.44313726f), //
|
||||
new Color3f(0.21960784f, 0.21960784f, 0.44313726f), new Color3f(0.27058825f, 0.21960784f, 0.44313726f), //
|
||||
new Color3f(0.33333334f, 0.21960784f, 0.44313726f), new Color3f(0.38039216f, 0.21960784f, 0.44313726f), //
|
||||
new Color3f(0.44313726f, 0.21960784f, 0.44313726f), new Color3f(0.44313726f, 0.21960784f, 0.38039216f), //
|
||||
new Color3f(0.44313726f, 0.21960784f, 0.33333334f), new Color3f(0.44313726f, 0.21960784f, 0.27058825f), //
|
||||
new Color3f(0.44313726f, 0.21960784f, 0.21960784f), new Color3f(0.44313726f, 0.27058825f, 0.21960784f), //
|
||||
new Color3f(0.44313726f, 0.33333334f, 0.21960784f), new Color3f(0.44313726f, 0.38039216f, 0.21960784f), //
|
||||
new Color3f(0.44313726f, 0.44313726f, 0.21960784f), new Color3f(0.38039216f, 0.44313726f, 0.21960784f), //
|
||||
new Color3f(0.33333334f, 0.44313726f, 0.21960784f), new Color3f(0.27058825f, 0.44313726f, 0.21960784f), //
|
||||
new Color3f(0.21960784f, 0.44313726f, 0.21960784f), new Color3f(0.21960784f, 0.44313726f, 0.27058825f), //
|
||||
new Color3f(0.21960784f, 0.44313726f, 0.33333334f), new Color3f(0.21960784f, 0.44313726f, 0.38039216f), //
|
||||
new Color3f(0.21960784f, 0.44313726f, 0.44313726f), new Color3f(0.21960784f, 0.38039216f, 0.44313726f), //
|
||||
new Color3f(0.21960784f, 0.33333334f, 0.44313726f), new Color3f(0.21960784f, 0.27058825f, 0.44313726f), //
|
||||
new Color3f(0.31764707f, 0.31764707f, 0.44313726f), new Color3f(0.34901962f, 0.31764707f, 0.44313726f), //
|
||||
new Color3f(0.38039216f, 0.31764707f, 0.44313726f), new Color3f(0.4117647f, 0.31764707f, 0.44313726f), //
|
||||
new Color3f(0.44313726f, 0.31764707f, 0.44313726f), new Color3f(0.44313726f, 0.31764707f, 0.4117647f), //
|
||||
new Color3f(0.44313726f, 0.31764707f, 0.38039216f), new Color3f(0.44313726f, 0.31764707f, 0.34901962f), //
|
||||
new Color3f(0.44313726f, 0.31764707f, 0.31764707f), new Color3f(0.44313726f, 0.34901962f, 0.31764707f), //
|
||||
new Color3f(0.44313726f, 0.38039216f, 0.31764707f), new Color3f(0.44313726f, 0.4117647f, 0.31764707f), //
|
||||
new Color3f(0.44313726f, 0.44313726f, 0.31764707f), new Color3f(0.4117647f, 0.44313726f, 0.31764707f), //
|
||||
new Color3f(0.38039216f, 0.44313726f, 0.31764707f), new Color3f(0.34901962f, 0.44313726f, 0.31764707f), //
|
||||
new Color3f(0.31764707f, 0.44313726f, 0.31764707f), new Color3f(0.31764707f, 0.44313726f, 0.34901962f), //
|
||||
new Color3f(0.31764707f, 0.44313726f, 0.38039216f), new Color3f(0.31764707f, 0.44313726f, 0.4117647f), //
|
||||
new Color3f(0.31764707f, 0.44313726f, 0.44313726f), new Color3f(0.31764707f, 0.4117647f, 0.44313726f), //
|
||||
new Color3f(0.31764707f, 0.38039216f, 0.44313726f), new Color3f(0.31764707f, 0.34901962f, 0.44313726f), //
|
||||
new Color3f(0.0f, 0.0f, 0.25490198f), new Color3f(0.0627451f, 0.0f, 0.25490198f), //
|
||||
new Color3f(0.1254902f, 0.0f, 0.25490198f), new Color3f(0.1882353f, 0.0f, 0.25490198f), //
|
||||
new Color3f(0.25490198f, 0.0f, 0.25490198f), new Color3f(0.25490198f, 0.0f, 0.1882353f), //
|
||||
new Color3f(0.25490198f, 0.0f, 0.1254902f), new Color3f(0.25490198f, 0.0f, 0.0627451f), //
|
||||
new Color3f(0.25490198f, 0.0f, 0.0f), new Color3f(0.25490198f, 0.0627451f, 0.0f), //
|
||||
new Color3f(0.25490198f, 0.1254902f, 0.0f), new Color3f(0.25490198f, 0.1882353f, 0.0f), //
|
||||
new Color3f(0.25490198f, 0.25490198f, 0.0f), new Color3f(0.1882353f, 0.25490198f, 0.0f), //
|
||||
new Color3f(0.1254902f, 0.25490198f, 0.0f), new Color3f(0.0627451f, 0.25490198f, 0.0f), //
|
||||
new Color3f(0.0f, 0.25490198f, 0.0f), new Color3f(0.0f, 0.25490198f, 0.0627451f), //
|
||||
new Color3f(0.0f, 0.25490198f, 0.1254902f), new Color3f(0.0f, 0.25490198f, 0.1882353f), //
|
||||
new Color3f(0.0f, 0.25490198f, 0.25490198f), new Color3f(0.0f, 0.1882353f, 0.25490198f), //
|
||||
new Color3f(0.0f, 0.1254902f, 0.25490198f), new Color3f(0.0f, 0.0627451f, 0.25490198f), //
|
||||
new Color3f(0.1254902f, 0.1254902f, 0.25490198f), new Color3f(0.15686275f, 0.1254902f, 0.25490198f), //
|
||||
new Color3f(0.1882353f, 0.1254902f, 0.25490198f), new Color3f(0.21960784f, 0.1254902f, 0.25490198f), //
|
||||
new Color3f(0.25490198f, 0.1254902f, 0.25490198f), new Color3f(0.25490198f, 0.1254902f, 0.21960784f), //
|
||||
new Color3f(0.25490198f, 0.1254902f, 0.1882353f), new Color3f(0.25490198f, 0.1254902f, 0.15686275f), //
|
||||
new Color3f(0.25490198f, 0.1254902f, 0.1254902f), new Color3f(0.25490198f, 0.15686275f, 0.1254902f), //
|
||||
new Color3f(0.25490198f, 0.1882353f, 0.1254902f), new Color3f(0.25490198f, 0.21960784f, 0.1254902f), //
|
||||
new Color3f(0.25490198f, 0.25490198f, 0.1254902f), new Color3f(0.21960784f, 0.25490198f, 0.1254902f), //
|
||||
new Color3f(0.1882353f, 0.25490198f, 0.1254902f), new Color3f(0.15686275f, 0.25490198f, 0.1254902f), //
|
||||
new Color3f(0.1254902f, 0.25490198f, 0.1254902f), new Color3f(0.1254902f, 0.25490198f, 0.15686275f), //
|
||||
new Color3f(0.1254902f, 0.25490198f, 0.1882353f), new Color3f(0.1254902f, 0.25490198f, 0.21960784f), //
|
||||
new Color3f(0.1254902f, 0.25490198f, 0.25490198f), new Color3f(0.1254902f, 0.21960784f, 0.25490198f), //
|
||||
new Color3f(0.1254902f, 0.1882353f, 0.25490198f), new Color3f(0.1254902f, 0.15686275f, 0.25490198f), //
|
||||
new Color3f(0.17254902f, 0.17254902f, 0.25490198f), new Color3f(0.1882353f, 0.17254902f, 0.25490198f), //
|
||||
new Color3f(0.20392157f, 0.17254902f, 0.25490198f), new Color3f(0.23529412f, 0.17254902f, 0.25490198f), //
|
||||
new Color3f(0.25490198f, 0.17254902f, 0.25490198f), new Color3f(0.25490198f, 0.17254902f, 0.23529412f), //
|
||||
new Color3f(0.25490198f, 0.17254902f, 0.20392157f), new Color3f(0.25490198f, 0.17254902f, 0.1882353f), //
|
||||
new Color3f(0.25490198f, 0.17254902f, 0.17254902f), new Color3f(0.25490198f, 0.1882353f, 0.17254902f), //
|
||||
new Color3f(0.25490198f, 0.20392157f, 0.17254902f), new Color3f(0.25490198f, 0.23529412f, 0.17254902f), //
|
||||
new Color3f(0.25490198f, 0.25490198f, 0.17254902f), new Color3f(0.23529412f, 0.25490198f, 0.17254902f), //
|
||||
new Color3f(0.20392157f, 0.25490198f, 0.17254902f), new Color3f(0.1882353f, 0.25490198f, 0.17254902f), //
|
||||
new Color3f(0.17254902f, 0.25490198f, 0.17254902f), new Color3f(0.17254902f, 0.25490198f, 0.1882353f), //
|
||||
new Color3f(0.17254902f, 0.25490198f, 0.20392157f), new Color3f(0.17254902f, 0.25490198f, 0.23529412f), //
|
||||
new Color3f(0.17254902f, 0.25490198f, 0.25490198f), new Color3f(0.17254902f, 0.23529412f, 0.25490198f), //
|
||||
new Color3f(0.17254902f, 0.20392157f, 0.25490198f), new Color3f(0.17254902f, 0.1882353f, 0.25490198f), //
|
||||
new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.0f, 0.0f, 0.0f), //
|
||||
new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.0f, 0.0f, 0.0f), //
|
||||
new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.0f, 0.0f, 0.0f), //
|
||||
new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.0f, 0.0f, 0.0f), //
|
||||
new Color3f(0.0f, 0.0f, 0.0f)};
|
||||
}
|
58
src/digisoft/custom/math/NumberConstants.java
Normal file
58
src/digisoft/custom/math/NumberConstants.java
Normal file
|
@ -0,0 +1,58 @@
|
|||
package digisoft.custom.math;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/26
|
||||
*/
|
||||
public interface NumberConstants {
|
||||
|
||||
public static final double COS1 = 0.54030230586813971740093660744297660373231042061792; // Knuth31
|
||||
public static final double CUBERT2 = 1.25992104989487316476721060727822835057025146470151; // Knuth05
|
||||
public static final double CUBERT3 = 1.44224957030740838232163831078010958839186925349935; // Knuth06
|
||||
public static final double DEG_TO_RAD = 0.01745329251994329576923690768488612713442871888542; // Knuth18
|
||||
public static final double E = 2.71828182845904523536028747135266249775724709369996; // Knuth24
|
||||
public static final double EULERGAMMA = 0.57721566490153286060651209008240243104215933593992; // Knuth27
|
||||
public static final double EXP_EULERGAMMA = 1.7810724179901979852365041031071795491696452143034; // Knuth28
|
||||
public static final double EXP_PI025 = 2.19328005073801545655976965927873822346163764199427; // Knuth29
|
||||
public static final double E_SQR = 7.38905609893065022723042746057500781318031557055185; // Knuth26
|
||||
public static final double GAMMA033 = 2.6789385347077476336556929409746776441286893779573; // Knuth22
|
||||
public static final double GAMMA05 = 1.7724538509055160272981674833411451827975494561224; // Knuth21
|
||||
public static final double GAMMA067 = 1.3541179394264004169452880281545137855193272660568; // Knuth23
|
||||
public static final double LOG10 = 2.30258509299404568401799145468436420760110148862877; // Knuth11
|
||||
public static final double LOG2 = 0.69314718055994530941723212145817656807550013436026; // Knuth09
|
||||
public static final double LOG3 = 1.09861228866810969139524523692252570464749055782275; // Knuth10
|
||||
public static final double LOGPHI = 0.48121182505960344749775891342436842313518433438566; // Knuth13
|
||||
public static final double LOGPI = 1.14472988584940017414342735135305871164729481291531; // Knuth12
|
||||
public static final double LOGR10 = 0.43429448190325182765112891891660508229439700580367;
|
||||
public static final double LOGR2 = 1.44269504088896340735992468100189213742664595415299;
|
||||
public static final double NLOGLOG2 = 0.36651292058166432701243915823266946945426344783711; // Knuth33
|
||||
public static final double PHI = 1.61803398874989484820458683436563811772030917980576; // Knuth08
|
||||
public static final double PI = 3.14159265358979323846264338327950288419716939937511; // Knuth17
|
||||
public static final double PI05 = 1.57079632679489661923132169163975144209858469968755;
|
||||
public static final double PI2 = 6.28318530717958647692528676655900576839433879875021;
|
||||
public static final double PI_SQR = 9.86960440108935861883449099987615113531369940724079; // Knuth20
|
||||
public static final double Q05LOG10 = 0.21714724095162591382556445945830254114719850290183;
|
||||
public static final double Q05LOG2 = 0.72134752044448170367996234050094606871332297707649;
|
||||
public static final double Q05PI = 0.15915494309189533576888376337251436203445964574046;
|
||||
public static final double Q1_3 = 0.33333333333333333333333333333333333333333333333333;
|
||||
public static final double Q1_6 = 0.16666666666666666666666666666666666666666666666667;
|
||||
public static final double Q1E = 0.36787944117144232159552377016146086744581113103177; // Knuth25
|
||||
public static final double Q1LOG10 = 0.43429448190325182765112891891660508229439700580367; // Knuth15
|
||||
public static final double Q1LOG2 = 1.44269504088896340735992468100189213742664595415299; // Knuth14
|
||||
public static final double Q1LOGPHI = 2.07808692123502753760132260611779576774219226778328; // Knuth16
|
||||
public static final double Q1PI = 0.31830988618379067153776752674502872406891929148091; // Knuth19
|
||||
public static final double Q2PI = 0.63661977236758134307553505349005744813783858296183; //
|
||||
public static final double Q2POW025 = 1.18920711500272106671749997056047591529297209246382; // Knuth07
|
||||
public static final double Q2SQRT5 = 0.89442719099991587856366946749251049417624734384461;
|
||||
public static final double RAD_TO_DEG = 57.2957795130823208767981548141051703324054724665643;
|
||||
public static final double SIN1 = 0.84147098480789650665250232163029899962256306079837; // Knuth30
|
||||
public static final double SQRT02 = 0.44721359549995793928183473374625524708812367192231;
|
||||
public static final double SQRT05 = 0.70710678118654752440084436210484903928483593768847;
|
||||
public static final double SQRT075 = 0.86602540378443864676372317075293618347140262690519;
|
||||
public static final double SQRT10 = 3.16227766016837933199889354443271853371955513932522; // Knuth04
|
||||
public static final double SQRT2 = 1.41421356237309504880168872420969807856967187537695; // Knuth01
|
||||
public static final double SQRT3 = 1.73205080756887729352744634150587236694280525381038; // Knuth02
|
||||
public static final double SQRT5 = 2.23606797749978969640917366873127623544061835961153; // Knuth03
|
||||
public static final double ZETA3 = 1.2020569031595942853997381615114499907649862923405; // Knuth32
|
||||
}
|
87
src/digisoft/custom/swing/GraphicsFunctions.java
Normal file
87
src/digisoft/custom/swing/GraphicsFunctions.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
package digisoft.custom.swing;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.DisplayMode;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2007/12/01
|
||||
*/
|
||||
public class GraphicsFunctions {
|
||||
|
||||
public static final BasicStroke DEFAULT_SQUARE_STROKE = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
|
||||
public static final BasicStroke DEFAULT_ROUND_STROKE = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
|
||||
|
||||
public static void setNiceLookAndFeel() {
|
||||
try {
|
||||
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setAntialiased(Graphics2D g, boolean antialiased) {
|
||||
if (antialiased && g.getRenderingHint(RenderingHints.KEY_ANTIALIASING) != RenderingHints.VALUE_ANTIALIAS_ON) {
|
||||
g.translate(0.5, 0.5);
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
||||
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
}
|
||||
if (!antialiased && g.getRenderingHint(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON) {
|
||||
g.translate(-0.5, -0.5);
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT);
|
||||
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT);
|
||||
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DEFAULT);
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
|
||||
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT);
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
|
||||
g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_DEFAULT);
|
||||
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
public static GraphicsDevice getDisplayDevice() {
|
||||
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
||||
}
|
||||
|
||||
public static DisplayMode getDisplayMode(int width, int height) {
|
||||
DisplayMode currentMode = GraphicsFunctions.getDisplayDevice().getDisplayMode();
|
||||
DisplayMode[] modes = GraphicsFunctions.getDisplayDevice().getDisplayModes();
|
||||
|
||||
int bitDepth = currentMode.getBitDepth();
|
||||
int refreshRate = currentMode.getRefreshRate();
|
||||
|
||||
for (DisplayMode mode : modes) {
|
||||
if (mode.getHeight() == height && mode.getWidth() == width && mode.getBitDepth() == bitDepth && mode.getRefreshRate() == refreshRate) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
refreshRate = Integer.MAX_VALUE;
|
||||
int index = -1;
|
||||
for (int i = modes.length - 1; i >= 0; i--) {
|
||||
DisplayMode mode = modes[i];
|
||||
if (mode.getHeight() == height && mode.getWidth() == width && mode.getBitDepth() == bitDepth) {
|
||||
if (refreshRate > mode.getRefreshRate()) {
|
||||
refreshRate = mode.getRefreshRate();
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index < 0 ? null : modes[index];
|
||||
}
|
||||
}
|
100
src/digisoft/custom/swing/ImageFunctions.java
Normal file
100
src/digisoft/custom/swing/ImageFunctions.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
package digisoft.custom.swing;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import com.sun.image.codec.jpeg.JPEGCodec;
|
||||
import com.sun.image.codec.jpeg.JPEGEncodeParam;
|
||||
import com.sun.image.codec.jpeg.JPEGImageEncoder;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/28
|
||||
*/
|
||||
public class ImageFunctions {
|
||||
|
||||
public static final int SCALE_HINT_ALWAYS = 0;
|
||||
public static final int SCALE_HINT_FIT_INSIDE = 1;
|
||||
public static final int SCALE_HINT_WHEN_NECESSARY = 2;
|
||||
|
||||
public static ImageIcon scaleImage(ImageIcon imageIcon, int width, int height, int scalingHint) {
|
||||
switch (scalingHint) {
|
||||
case SCALE_HINT_WHEN_NECESSARY: {
|
||||
if (imageIcon.getIconWidth() <= width && imageIcon.getIconHeight() <= height) {
|
||||
return imageIcon;
|
||||
}
|
||||
// Fall through.
|
||||
}
|
||||
case SCALE_HINT_ALWAYS: {
|
||||
return ImageFunctions.scaleImage(imageIcon, width, height);
|
||||
}
|
||||
case SCALE_HINT_FIT_INSIDE: {
|
||||
Image image = imageIcon.getImage();
|
||||
|
||||
double wf = (double) width / image.getWidth(null);
|
||||
double hf = (double) height / image.getHeight(null);
|
||||
|
||||
if (wf > hf) {
|
||||
height = (int) (wf * image.getHeight(null) + 0.5);
|
||||
} else if (hf > wf) {
|
||||
width = (int) (hf * image.getWidth(null) + 0.5);
|
||||
}
|
||||
|
||||
// imageIcon.setImage(image.getScaledInstance(width, height,
|
||||
// Image.SCALE_AREA_AVERAGING));
|
||||
// return imageIcon;
|
||||
return new ImageIcon(image.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING));
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Illegal scalingHint. Must be one of SCALE_HINT_ALWAYS, SCALE_HINT_FIT_INSIDE, SCALE_HINT_WHEN_NECESSARY");
|
||||
}
|
||||
|
||||
public static ImageIcon scaleImage(ImageIcon imageIcon, int width, int height) {
|
||||
Image image = imageIcon.getImage();
|
||||
|
||||
double wf = (double) width / image.getWidth(null);
|
||||
double hf = (double) height / image.getHeight(null);
|
||||
|
||||
if (wf < hf) {
|
||||
height = (int) (wf * image.getHeight(null) + 0.5);
|
||||
} else if (hf < wf) {
|
||||
width = (int) (hf * image.getWidth(null) + 0.5);
|
||||
}
|
||||
|
||||
// imageIcon.setImage(image.getScaledInstance(width, height,
|
||||
// Image.SCALE_AREA_AVERAGING));
|
||||
// return imageIcon;
|
||||
return new ImageIcon(image.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING));
|
||||
}
|
||||
|
||||
public static void saveJPEG(String filename, int[] pixels, int width, int height) throws IOException {
|
||||
BufferedImage saveImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
|
||||
saveImage.setRGB(0, 0, width, height, pixels, 0, width);
|
||||
|
||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(filename));
|
||||
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
|
||||
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(saveImage);
|
||||
param.setQuality(0.95f, false);
|
||||
encoder.setJPEGEncodeParam(param);
|
||||
encoder.encode(saveImage);
|
||||
out.close();
|
||||
}
|
||||
|
||||
public static void savePNG(String filename, int[] pixels, int width, int height) throws IOException {
|
||||
BufferedImage saveImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
saveImage.setRGB(0, 0, width, height, pixels, 0, width);
|
||||
|
||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(filename));
|
||||
ImageIO.write(saveImage, "png", out);
|
||||
|
||||
out.close();
|
||||
}
|
||||
}
|
11
src/digisoft/custom/swing/RefreshListener.java
Normal file
11
src/digisoft/custom/swing/RefreshListener.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package digisoft.custom.swing;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2008/12/27
|
||||
*/
|
||||
public interface RefreshListener {
|
||||
|
||||
public void refreshing();
|
||||
}
|
39
src/digisoft/custom/swing/RefreshThread.java
Normal file
39
src/digisoft/custom/swing/RefreshThread.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package digisoft.custom.swing;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/16
|
||||
*/
|
||||
public class RefreshThread extends Thread {
|
||||
|
||||
private double delay;
|
||||
private RefreshListener runnable;
|
||||
|
||||
public RefreshThread(RefreshListener refreshListener, int fps) {
|
||||
super();
|
||||
|
||||
runnable = refreshListener;
|
||||
delay = 1e9 / fps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
double t = System.nanoTime();
|
||||
while (true) {
|
||||
runnable.refreshing();
|
||||
|
||||
t += delay;
|
||||
|
||||
long sleepTime = (long) ((t - System.nanoTime()) / 1e6);
|
||||
|
||||
if (sleepTime > 0) {
|
||||
Thread.sleep(sleepTime);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
19
src/digisoft/custom/swing/gradient/Gradient.java
Normal file
19
src/digisoft/custom/swing/gradient/Gradient.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
package digisoft.custom.swing.gradient;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/19
|
||||
*/
|
||||
public interface Gradient {
|
||||
|
||||
public boolean hasTransparency();
|
||||
|
||||
public int getLength();
|
||||
|
||||
public int get(int index);
|
||||
|
||||
public int get(double position);
|
||||
|
||||
public int getOverflow();
|
||||
}
|
108
src/digisoft/custom/swing/gradient/OpaqueGradient.java
Normal file
108
src/digisoft/custom/swing/gradient/OpaqueGradient.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
package digisoft.custom.swing.gradient;
|
||||
|
||||
import digisoft.custom.awt.Color3f;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/05
|
||||
*/
|
||||
public class OpaqueGradient implements Gradient {
|
||||
|
||||
private static final int MAX_GRADIENT_ARRAY_SIZE = 5000;
|
||||
private static final int GRADIENT_SIZE = 256;
|
||||
private float[] fractions;
|
||||
private int gradientOverflow;
|
||||
private float[] intervals;
|
||||
private int gradientLength;
|
||||
private int[] gradient;
|
||||
|
||||
public OpaqueGradient(float[] fractions, Color3f[] colors) {
|
||||
this.fractions = fractions;
|
||||
|
||||
gradientOverflow = colors[colors.length - 1].getRGB();
|
||||
|
||||
intervals = new float[fractions.length - 1];
|
||||
for (int i = 0; i < intervals.length; i++) {
|
||||
intervals[i] = fractions[i + 1] - fractions[i];
|
||||
}
|
||||
|
||||
calculateGradientFractions(colors);
|
||||
}
|
||||
|
||||
private void calculateGradientFractions(Color3f[] colors) {
|
||||
int n = intervals.length;
|
||||
|
||||
// Find smallest interval
|
||||
float Imin = 1;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (Imin > intervals[i]) {
|
||||
Imin = intervals[i];
|
||||
}
|
||||
}
|
||||
|
||||
calculateSingleArrayGradient(colors, Imin);
|
||||
|
||||
}
|
||||
|
||||
private void calculateSingleArrayGradient(Color3f[] colors, float Imin) {
|
||||
|
||||
gradientLength = (int) (OpaqueGradient.GRADIENT_SIZE / Imin + 0.5);
|
||||
if (gradientLength > OpaqueGradient.MAX_GRADIENT_ARRAY_SIZE) {
|
||||
gradientLength = OpaqueGradient.MAX_GRADIENT_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
gradient = new int[gradientLength + 1];
|
||||
int part = 0;
|
||||
for (int i = 0; i <= gradientLength; i++) {
|
||||
// Fraction of the gradient.
|
||||
float f = (float) i / gradientLength;
|
||||
|
||||
// Select interval.
|
||||
while (f > fractions[part + 1]) {
|
||||
part++;
|
||||
}
|
||||
|
||||
// Fraction of the current interval.
|
||||
float p = (f - fractions[part]) / intervals[part];
|
||||
|
||||
// 2 colors to interpolate
|
||||
Color3f c1 = colors[part];
|
||||
Color3f c2 = colors[part + 1];
|
||||
|
||||
gradient[i] = interpolate(c1, c2, p);
|
||||
}
|
||||
}
|
||||
|
||||
private int interpolate(Color3f c1, Color3f c2, float p) {
|
||||
return 0xFF000000 //
|
||||
| (int) ((c1.r + (c2.r - c1.r) * p) * 255 + .5) << 16 //
|
||||
| (int) ((c1.g + (c2.g - c1.g) * p) * 255 + .5) << 8//
|
||||
| (int) ((c1.b + (c2.b - c1.b) * p) * 255 + .5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTransparency() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return gradientLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(int index) {
|
||||
return gradient[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(double position) {
|
||||
return gradient[(int) (position * gradientLength + 0.5)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOverflow() {
|
||||
return gradientOverflow;
|
||||
}
|
||||
}
|
165
src/digisoft/custom/swing/window/CanvasWindow.java
Normal file
165
src/digisoft/custom/swing/window/CanvasWindow.java
Normal file
|
@ -0,0 +1,165 @@
|
|||
package digisoft.custom.swing.window;
|
||||
|
||||
import java.awt.DisplayMode;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import digisoft.custom.swing.GraphicsFunctions;
|
||||
import digisoft.custom.swing.window.canvas.GraphicsCanvas;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/03/22
|
||||
*/
|
||||
public class CanvasWindow extends JFrame {
|
||||
|
||||
/**
|
||||
* Creates a fullscreen CanvasWindow using a given GraphicsCanvas
|
||||
*
|
||||
*
|
||||
* @param canvas
|
||||
* the GraphicsCanvas defining the drawing method
|
||||
* @param x
|
||||
* the x-position of the upper-left corner of the window
|
||||
* @param y
|
||||
* the y-position of the upper-left corner of the window
|
||||
* @param width
|
||||
* the width of the drawable area of the window
|
||||
* @param height
|
||||
* the height of the drawable area of the window
|
||||
*/
|
||||
public CanvasWindow(GraphicsCanvas canvas, int x, int y, int width, int height) {
|
||||
super();
|
||||
|
||||
this.setup(canvas, width, height);
|
||||
|
||||
super.setResizable(false);
|
||||
super.pack();
|
||||
super.setLocation(x, y);
|
||||
super.setVisible(true);
|
||||
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(CanvasWindow.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
canvas.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fullscreen CanvasWindow using a given GraphicsCanvas
|
||||
*
|
||||
*
|
||||
* @param canvas
|
||||
* the GraphicsCanvas defining the drawing method
|
||||
* @param width
|
||||
* the width of the drawable area of the window
|
||||
* @param height
|
||||
* the height of the drawable area of the window
|
||||
*/
|
||||
public CanvasWindow(GraphicsCanvas canvas, int width, int height) {
|
||||
super();
|
||||
|
||||
this.setup(canvas, width, height);
|
||||
|
||||
super.setResizable(false);
|
||||
super.pack();
|
||||
super.setLocationRelativeTo(null);
|
||||
super.setVisible(true);
|
||||
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(CanvasWindow.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
canvas.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fullscreen CanvasWindow using a given GraphicsCanvas
|
||||
*
|
||||
* @param canvas
|
||||
* the GraphicsCanvas defining the drawing method
|
||||
* @param exclusive
|
||||
* when this is set, the window becomes fullscreen, otherwise, it
|
||||
* will stretch to fit the screen.
|
||||
*/
|
||||
public CanvasWindow(GraphicsCanvas canvas, boolean exclusive) {
|
||||
super();
|
||||
|
||||
GraphicsDevice displayDevice = GraphicsFunctions.getDisplayDevice();
|
||||
DisplayMode mode = displayDevice.getDisplayMode();
|
||||
int width = mode.getWidth();
|
||||
int height = mode.getHeight();
|
||||
|
||||
this.setup(canvas, width, height);
|
||||
|
||||
super.invalidate();
|
||||
super.setUndecorated(true);
|
||||
|
||||
super.setResizable(false);
|
||||
super.pack();
|
||||
super.setLocationRelativeTo(null);
|
||||
|
||||
if (exclusive) {
|
||||
displayDevice.setFullScreenWindow(this);
|
||||
} else {
|
||||
super.setBounds(new Rectangle(0, 0, width, height));
|
||||
super.setVisible(true);
|
||||
}
|
||||
|
||||
canvas.requestFocus();
|
||||
}
|
||||
|
||||
public CanvasWindow(GraphicsCanvas canvas, DisplayMode mode) {
|
||||
super();
|
||||
|
||||
GraphicsDevice displayDevice = GraphicsFunctions.getDisplayDevice();
|
||||
int width = mode.getWidth();
|
||||
int height = mode.getHeight();
|
||||
|
||||
this.setup(canvas, width, height);
|
||||
|
||||
super.invalidate();
|
||||
super.setUndecorated(true);
|
||||
|
||||
super.setResizable(false);
|
||||
super.pack();
|
||||
super.setLocationRelativeTo(null);
|
||||
|
||||
displayDevice.setFullScreenWindow(this);
|
||||
displayDevice.setDisplayMode(mode);
|
||||
|
||||
canvas.requestFocus();
|
||||
}
|
||||
|
||||
private void setup(GraphicsCanvas canvas, int width, int height) {
|
||||
super.setName(this.getClass().getSimpleName());
|
||||
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
super.setLayout(null);
|
||||
|
||||
{
|
||||
canvas.init(width, height, false);
|
||||
|
||||
super.setContentPane(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void setExclusive(boolean b) {
|
||||
GraphicsFunctions.getDisplayDevice().setFullScreenWindow(b ? this : null);
|
||||
|
||||
GraphicsCanvas canvas = (GraphicsCanvas) this.getContentPane();
|
||||
if (b) {
|
||||
super.setBounds(new Rectangle(0, 0, canvas.width, canvas.height));
|
||||
} else {
|
||||
super.pack();
|
||||
}
|
||||
}
|
||||
}
|
96
src/digisoft/custom/swing/window/PixelWindow.java
Normal file
96
src/digisoft/custom/swing/window/PixelWindow.java
Normal file
|
@ -0,0 +1,96 @@
|
|||
package digisoft.custom.swing.window;
|
||||
|
||||
import java.awt.DisplayMode;
|
||||
|
||||
import digisoft.custom.swing.GraphicsFunctions;
|
||||
import digisoft.custom.swing.window.canvas.MemoryImageSourceCanvas;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/04/04
|
||||
*/
|
||||
public class PixelWindow extends MemoryImageSourceCanvas {
|
||||
|
||||
private CanvasWindow window;
|
||||
private DisplayMode backupMode = null;
|
||||
|
||||
/**
|
||||
* Creates a fullscreen CanvasWindow using a given GraphicsCanvas
|
||||
*
|
||||
*
|
||||
* @param x
|
||||
* the x-position of the upper-left corner of the window
|
||||
* @param y
|
||||
* the y-position of the upper-left corner of the window
|
||||
* @param width
|
||||
* the width of the drawable area of the window
|
||||
* @param height
|
||||
* the height of the drawable area of the window
|
||||
*/
|
||||
public PixelWindow(int x, int y, int width, int height) {
|
||||
super();
|
||||
|
||||
window = new CanvasWindow(this, x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fullscreen CanvasWindow using a given GraphicsCanvas
|
||||
*
|
||||
*
|
||||
* @param width
|
||||
* the width of the drawable area of the window
|
||||
* @param height
|
||||
* the height of the drawable area of the window
|
||||
*/
|
||||
public PixelWindow(int width, int height) {
|
||||
super();
|
||||
|
||||
window = new CanvasWindow(this, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fullscreen CanvasWindow using a given GraphicsCanvas
|
||||
*
|
||||
* @param exclusive
|
||||
* when this is set, the window becomes fullscreen, otherwise, it
|
||||
* will stretch to fit the screen.
|
||||
*/
|
||||
public PixelWindow(boolean exclusive) {
|
||||
super();
|
||||
|
||||
window = new CanvasWindow(this, exclusive);
|
||||
}
|
||||
|
||||
public PixelWindow(DisplayMode mode) {
|
||||
super();
|
||||
|
||||
backupMode = GraphicsFunctions.getDisplayDevice().getDisplayMode();
|
||||
|
||||
window = new CanvasWindow(this, mode);
|
||||
|
||||
while (pixels == null) {
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
|
||||
public void setExclusive(boolean b) {
|
||||
window.setExclusive(b);
|
||||
}
|
||||
|
||||
public void setFullscreen(DisplayMode mode) {
|
||||
if (backupMode == null) {
|
||||
window.setExclusive(true);
|
||||
backupMode = GraphicsFunctions.getDisplayDevice().getDisplayMode();
|
||||
GraphicsFunctions.getDisplayDevice().setDisplayMode(mode);
|
||||
} else {
|
||||
GraphicsFunctions.getDisplayDevice().setDisplayMode(backupMode);
|
||||
window.setExclusive(false);
|
||||
backupMode = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTitle(String name) {
|
||||
window.setTitle(name);
|
||||
}
|
||||
}
|
131
src/digisoft/custom/swing/window/canvas/GraphicsCanvas.java
Normal file
131
src/digisoft/custom/swing/window/canvas/GraphicsCanvas.java
Normal file
|
@ -0,0 +1,131 @@
|
|||
package digisoft.custom.swing.window.canvas;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Paint;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/03/22
|
||||
*/
|
||||
public abstract class GraphicsCanvas extends JPanel implements ComponentListener {
|
||||
|
||||
public int width;
|
||||
public int height;
|
||||
public int halfWidth;
|
||||
public int halfHeight;
|
||||
private volatile boolean resizeRequest;
|
||||
protected Graphics pg = null;
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
public GraphicsCanvas() {
|
||||
addComponentListener(this);
|
||||
}
|
||||
|
||||
public void init(int width, int height, boolean painting) {
|
||||
if (this.width != width || this.height != height) {
|
||||
setPreferredSize(new Dimension(width, height));
|
||||
|
||||
initImpl(width, height);
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
halfWidth = width >> 1;
|
||||
halfHeight = height >> 1;
|
||||
|
||||
g = null;
|
||||
|
||||
if (painting) {
|
||||
resized();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
public void clear(Paint paint) {
|
||||
throw new Error("Engine " + this.getClass().getSimpleName() + " has no clear(Paint paint)");
|
||||
}
|
||||
|
||||
public void clear(int rgb) {
|
||||
throw new Error("Engine " + this.getClass().getSimpleName() + " has no clear(int rgb)");
|
||||
}
|
||||
|
||||
public void clear(int rgba, boolean hasAlpha) {
|
||||
throw new Error("Engine " + this.getClass().getSimpleName() + " has no clear(int rgba, boolean hasAlpha)");
|
||||
}
|
||||
|
||||
public void pset(int x, int y, int rgb) {
|
||||
throw new Error("Engine " + this.getClass().getSimpleName() + " has no pset(int x, int y, int rgb)");
|
||||
}
|
||||
|
||||
public int pget(int x, int y) {
|
||||
throw new Error("Engine " + this.getClass().getSimpleName() + " has no pget(int x, int y)");
|
||||
}
|
||||
|
||||
public Graphics2D graphics() {
|
||||
throw new Error("Engine " + this.getClass().getSimpleName() + " has no 2D graphics. Only pixel access supported.");
|
||||
}
|
||||
|
||||
public void setAntialiased(boolean b) {
|
||||
throw new Error("Engine " + this.getClass().getSimpleName() + " has no 2D graphics. No antialiasing supported.");
|
||||
}
|
||||
|
||||
protected abstract void initImpl(int width, int height);
|
||||
|
||||
protected abstract void paintImpl(Graphics g);
|
||||
|
||||
public boolean ready() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
public void resized() {
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
if (resizeRequest) {
|
||||
init(super.getWidth(), super.getHeight(), true);
|
||||
resizeRequest = false;
|
||||
} else {
|
||||
paintImpl(g);
|
||||
}
|
||||
}
|
||||
private Graphics2D g = null;
|
||||
|
||||
public void repaintNow() {
|
||||
if (g == null) {
|
||||
g = (Graphics2D) getGraphics();
|
||||
}
|
||||
paint(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
System.out.println("componentResized " + width + "\t" + height);
|
||||
if (width != super.getWidth() || height != super.getHeight()) {
|
||||
resizeRequest = true;
|
||||
}
|
||||
super.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent arg0) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package digisoft.custom.swing.window.canvas;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.MemoryImageSource;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Zom-B
|
||||
* @since 1.0
|
||||
* @date 2009/03/22
|
||||
*/
|
||||
public class MemoryImageSourceCanvas extends GraphicsCanvas {
|
||||
|
||||
private Image image;
|
||||
public int[] pixels;
|
||||
public int pixelCount;
|
||||
private ColorModel cm;
|
||||
private MemoryImageSource source;
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
@Override
|
||||
public void clear(int backgroundColor) {
|
||||
Arrays.fill(pixels, backgroundColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pset(int x, int y, int rgb) {
|
||||
pixels[y * width + x] = rgb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pget(int x, int y) {
|
||||
return pixels[y * width + x];
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
@Override
|
||||
protected void initImpl(int width, int height) {
|
||||
pixelCount = width * height;
|
||||
|
||||
if (pixels == null || pixels.length < pixelCount) {
|
||||
pixels = new int[pixelCount];
|
||||
}
|
||||
|
||||
cm = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff);
|
||||
source = new MemoryImageSource(width, height, pixels, 0, width);
|
||||
source.setFullBufferUpdates(true);
|
||||
source.setAnimated(true);
|
||||
image = Toolkit.getDefaultToolkit().createImage(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintImpl(Graphics g) {
|
||||
if (source != null) {
|
||||
source.newPixels(pixels, cm, 0, width);
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
g.drawImage(image, 0, 0, null);
|
||||
|
||||
// force repaint now (proper method)
|
||||
// Toolkit.getDefaultToolkit().sync();
|
||||
}
|
||||
}
|
||||
}
|
1892
src/digisoft/custom/util/geom/DoubleDouble.java
Normal file
1892
src/digisoft/custom/util/geom/DoubleDouble.java
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue