Код: Выделить всё
public class RoundRect {
float width;
float height;
float r;
float fullWidth => width + r * 2;
float fullHeight => height + r * 2;
float radWidth => width + r;
float radHeight => height + r;
public float perimeter => (radWidth * 2 + radHeight * 2);
static Exception pointOut = new Exception("Point out of the rectangle");
public RoundRect(float width, float height, float radius) {
if (width < radius || height < radius) { throw new Exception("Radius should be less than dimensions"); }
this.width = width - 2*radius;
this.height = height - 2*radius;
r = radius;
}
public float CornerByAxisPoint(float p, bool positive) {
if (Mathf.Abs(p) > r) {
Debug.Log("Invalid input p: " + p + $". Must be within [-{r}, {r}]");
p = Mathf.Clamp(p, -r, r);
}
return Mathf.Sqrt(r * r - p * p) * (positive ? 1 : -1);
}
public Vector2 GetPointOnBase(float x, bool topSide) {
if (x width) { return new Vector2(x+(topSide ? 0 : -width*2-r), CornerByAxisPoint(x-width+(topSide ? 0 : -r), topSide)); }
else throw pointOut;
}
public Vector2 GetPointOnLegs(float y, bool rightSide) {
if (y height) { return new Vector2(CornerByAxisPoint(y-height, rightSide)+(rightSide ? -r : r), (rightSide ? -y : y)); }
else throw pointOut;
}
public Vector2 GetPoint(float p) {
Debug.Log(p);
if (p radWidth && p radWidth + radHeight && p radWidth*2 + radHeight && p GetPoint(Mathf.Lerp(0f, perimeter, t));
public static Vector3 OnGround(Vector2 point) {
return new Vector3(point.x, 0, point.y);
}
}

< /p>
Я использовал эпсилон, и неверный квадратный корень, казалось бы, больше не был проблемой, но основная проблема осталась: интерполяция по углам не очень хорошая, поэтому я вернул его обратно. Все точки должны быть расположены равномерно, без странных промежутков.
Редактировать: я понял, что алгоритм не имеет значения для сопоставления точек от 0 до периметра с использованием линейной интерполяции, поскольку четверти дуги единичного круга не являются симметричны на обоих концах, поскольку абсолютная разность y различна, что отражается и на тригонометрической волне. Что я делал для дуг, так это сопоставлял сброс точки обратно в 0 с единичным кругом диапазона (-1,1) и получал положение y, используя уравнение круга.
Подробнее здесь: https://stackoverflow.com/questions/790 ... erpolation