在 n 次迭代后趋向于给定数字的算法
Algorithm to trend towards a given number after n iterations
我正在尝试找到一个好的算法来完成以下任务:
我有两种 RGB 颜色。我从一种颜色(例如,红色 = 255、0、0)开始,经过多次迭代后,我希望它变成蓝色(0、0、255)。
我目前的算法只是将颜色的每个分量的总和除以二,这样可以解决问题,但速度太快了。在每次迭代中,我希望数字仅更改其原始值的十分之一。所以迭代 1 可能 return 颜色 (230, 0, 25) 等等。请记住,目标颜色也可以改变。所以突然我想要绿色而不是蓝色。
有谁知道完成这个的好方法吗?我似乎无法弄清楚数学。
谢谢!
好的 ol' 数学可以完成工作(像往常一样),所以让我们从更数学的方法开始:
value-space RGB: [0,255]^3
Let a,b e RGB , step_w, step_no e N
f(a , b , step_w , step_no) = (a0 + (b0 - a0) / step_w * step_no , a1 + (b1 ...
从数学到实际代码:
Color f(Color a , Color b , int step_w , int step_no){
return new Color(a.getRed() + (b.getRed() - a.getRed()) / step_w * step_no , a.getGreen() + (b.getGreen() - a.getGreen()) / step_w * step_no , ...);
}
step_w
是总步数,step_no
是到目前为止执行的步数。 f(c1 , c2 , x , y)
将 return c1
用于 y = 0
和 c2
用于 y = x
以及介于两者之间的匹配颜色用于 0 < y < x
.
虽然有更好的颜色转换方法(实验室颜色空间、HSL 等),看起来更自然。
已经有两篇关于其他颜色空间和线性方法的帖子。
但是,如果您真的正在寻找一种完全符合您要求的算法,请检查一下:
static class ColorChanger {
static private final int APPROACH_STEPS = 10;
private final Color mStartColor;
private final Color mTargetColor;
private int mApproachStep = 0;
private Color mCurrentColor;
public ColorChanger(final Color pStartColor, final Color pTargetColor) {
mStartColor = pStartColor;
mTargetColor = pTargetColor;
System.out.println("\nStarting color is: " + mStartColor);
System.out.println("Approaching target 1: " + mTargetColor);
}
public Color approach() {
++mApproachStep;
if (mApproachStep <= APPROACH_STEPS) { // dont overshoot target color. could throw an exception here too
final int newRedCode = nextColorCode(mStartColor.getRed(), mTargetColor.getRed());
final int newGreenCode = nextColorCode(mStartColor.getGreen(), mTargetColor.getGreen());
final int newBlueCode = nextColorCode(mStartColor.getBlue(), mTargetColor.getBlue());
mCurrentColor = new Color(newRedCode, newGreenCode, newBlueCode);
}
System.out.println("\tNew step color is: " + mCurrentColor);
return mCurrentColor;
}
private int nextColorCode(final int pCurrentCode, final int pTargetCode) {
final int diff = pTargetCode - pCurrentCode;
final int newCode = pCurrentCode + diff * mApproachStep / APPROACH_STEPS;
return newCode;
}
public Color getCurrentColor() {
return mCurrentColor;
}
public boolean isTargetColor() {
return mApproachStep == APPROACH_STEPS;
}
}
public static void main(final String[] args) {
final Color startColor = Color.RED;
final Color targetColor1 = Color.GREEN;
final Color targetColor2 = Color.BLUE;
final Color targetColor3 = Color.RED;
// approach in only 5 steps, will by far not reach target color
final ColorChanger cc1 = new ColorChanger(startColor, targetColor1);
for (int i = 0; i < 5; i++) {
cc1.approach();
}
// full approach #1
final ColorChanger cc2 = new ColorChanger(cc1.getCurrentColor(), targetColor2);
while (!cc2.isTargetColor()) {
cc2.approach();
}
// full approach #2
final ColorChanger cc3 = new ColorChanger(cc2.getCurrentColor(), targetColor3);
for (int i = 0; i < ColorChanger.APPROACH_STEPS; i++) {
cc3.approach();
}
System.out.println("Program ends");
}
我正在尝试找到一个好的算法来完成以下任务:
我有两种 RGB 颜色。我从一种颜色(例如,红色 = 255、0、0)开始,经过多次迭代后,我希望它变成蓝色(0、0、255)。
我目前的算法只是将颜色的每个分量的总和除以二,这样可以解决问题,但速度太快了。在每次迭代中,我希望数字仅更改其原始值的十分之一。所以迭代 1 可能 return 颜色 (230, 0, 25) 等等。请记住,目标颜色也可以改变。所以突然我想要绿色而不是蓝色。
有谁知道完成这个的好方法吗?我似乎无法弄清楚数学。
谢谢!
好的 ol' 数学可以完成工作(像往常一样),所以让我们从更数学的方法开始:
value-space RGB: [0,255]^3
Let a,b e RGB , step_w, step_no e N
f(a , b , step_w , step_no) = (a0 + (b0 - a0) / step_w * step_no , a1 + (b1 ...
从数学到实际代码:
Color f(Color a , Color b , int step_w , int step_no){
return new Color(a.getRed() + (b.getRed() - a.getRed()) / step_w * step_no , a.getGreen() + (b.getGreen() - a.getGreen()) / step_w * step_no , ...);
}
step_w
是总步数,step_no
是到目前为止执行的步数。 f(c1 , c2 , x , y)
将 return c1
用于 y = 0
和 c2
用于 y = x
以及介于两者之间的匹配颜色用于 0 < y < x
.
虽然有更好的颜色转换方法(实验室颜色空间、HSL 等),看起来更自然。
已经有两篇关于其他颜色空间和线性方法的帖子。
但是,如果您真的正在寻找一种完全符合您要求的算法,请检查一下:
static class ColorChanger {
static private final int APPROACH_STEPS = 10;
private final Color mStartColor;
private final Color mTargetColor;
private int mApproachStep = 0;
private Color mCurrentColor;
public ColorChanger(final Color pStartColor, final Color pTargetColor) {
mStartColor = pStartColor;
mTargetColor = pTargetColor;
System.out.println("\nStarting color is: " + mStartColor);
System.out.println("Approaching target 1: " + mTargetColor);
}
public Color approach() {
++mApproachStep;
if (mApproachStep <= APPROACH_STEPS) { // dont overshoot target color. could throw an exception here too
final int newRedCode = nextColorCode(mStartColor.getRed(), mTargetColor.getRed());
final int newGreenCode = nextColorCode(mStartColor.getGreen(), mTargetColor.getGreen());
final int newBlueCode = nextColorCode(mStartColor.getBlue(), mTargetColor.getBlue());
mCurrentColor = new Color(newRedCode, newGreenCode, newBlueCode);
}
System.out.println("\tNew step color is: " + mCurrentColor);
return mCurrentColor;
}
private int nextColorCode(final int pCurrentCode, final int pTargetCode) {
final int diff = pTargetCode - pCurrentCode;
final int newCode = pCurrentCode + diff * mApproachStep / APPROACH_STEPS;
return newCode;
}
public Color getCurrentColor() {
return mCurrentColor;
}
public boolean isTargetColor() {
return mApproachStep == APPROACH_STEPS;
}
}
public static void main(final String[] args) {
final Color startColor = Color.RED;
final Color targetColor1 = Color.GREEN;
final Color targetColor2 = Color.BLUE;
final Color targetColor3 = Color.RED;
// approach in only 5 steps, will by far not reach target color
final ColorChanger cc1 = new ColorChanger(startColor, targetColor1);
for (int i = 0; i < 5; i++) {
cc1.approach();
}
// full approach #1
final ColorChanger cc2 = new ColorChanger(cc1.getCurrentColor(), targetColor2);
while (!cc2.isTargetColor()) {
cc2.approach();
}
// full approach #2
final ColorChanger cc3 = new ColorChanger(cc2.getCurrentColor(), targetColor3);
for (int i = 0; i < ColorChanger.APPROACH_STEPS; i++) {
cc3.approach();
}
System.out.println("Program ends");
}