Trước tiên, bạn yêu cầu nội suy tuyến tính nhưng bạn không chỉ định màu B đó sống trên đường giữa màu A và màu C; Điều này là cần thiết. Thứ hai, bạn đã không chỉ định nhưng tôi sẽ làm cho một giả định đơn giản hóa rằng màu B là điểm giữa của đường thẳng giữa màu A và màu C; mã sau đây có thể dễ dàng sửa đổi nếu điều này không đúng. Cuối cùng, tôi đã thay đổi giả thiết của bạn rằng tham số là một số nguyên giữa 0 và một trăm là số nguyên giữa số không và một. Mã dễ viết hơn và dễ hiểu hơn trong trường hợp thứ hai, và vẫn có thể được sử dụng với trường hợp cũ (chia đầu vào của bạn cho một trăm).
class ColorInterpolator {
delegate byte ComponentSelector(Color color);
static ComponentSelector _redSelector = color => color.R;
static ComponentSelector _greenSelector = color => color.G;
static ComponentSelector _blueSelector = color => color.B;
public static Color InterpolateBetween(
Color endPoint1,
Color endPoint2,
double lambda) {
if (lambda < 0 || lambda > 1) {
throw new ArgumentOutOfRangeException("lambda");
}
Color color = Color.FromRgb(
InterpolateComponent(endPoint1, endPoint2, lambda, _redSelector),
InterpolateComponent(endPoint1, endPoint2, lambda, _greenSelector),
InterpolateComponent(endPoint1, endPoint2, lambda, _blueSelector)
);
return color;
}
static byte InterpolateComponent(
Color endPoint1,
Color endPoint2,
double lambda,
ComponentSelector selector) {
return (byte)(selector(endPoint1)
+ (selector(endPoint2) - selector(endPoint1)) * lambda);
}
}
Làm cách nào để bạn sửa đổi điều này nếu màu B không phải là điểm giữa màu A và màu C? Cách dễ nhất là như sau. Nếu tham số (cái tôi gọi là "lambda
") nhỏ hơn 0.5
, nhân lambda
bằng hai và trả về màu nội suy giữa màu A và màu B. Nếu tham số lớn hơn 0.5
, nhân lambda
bằng hai và trừ một (bản đồ này) [0.5, 1]
lên [0, 1]
) và trả lại màu nội suy giữa màu B và màu C.
Nếu bạn không thích yêu cầu màu B sống trên dòng giữa màu A và màu C, thì bạn có thể sử dụng chính xác sửa đổi Tôi chỉ mô tả để thực hiện một nội suy tuyến tính từng phần giữa các màu.
Cuối cùng, bạn không chỉ định nếu bạn muốn nội suy giá trị alpha được gọi là ('A' trong "ARGB"). Đoạn mã trên cũng dễ dàng sửa đổi để xử lý tình huống này. Thêm một số khác ComponentSelector
được định nghĩa là color => color.A
, sử dụng InterpolateComponent
để nội suy giá trị này và sử dụng quá tải Color.FromArgb(int, int, int, int)
của Color.FromArgb
.
Nó không thể được tuyến tính với ba điểm ngẫu nhiên – RBarryYoung