C
C#2mo ago
lil☆

Need help with fixing my rounded rectangle calculation

Hi! I'm making script for Unity. I'm bad at understanding floating points calculations and geometry, so it might be silly. Help me please
c#
public RoundRect(float width, float height, float r) {
if (width < r || height < r) { throw new Exception("Radius"); }
this.width = width - 2*r;
this.height = height - 2*r;
this.r = r;
public float CornerByAxisPoint(float p, bool positive) {
if (Mathf.Abs(p) > 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), (topSide ? r : -r)); }
else 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(0, y * (rightSide ? -1 : 1)); }
else if (y > height) { return new Vector2(CornerByAxisPoint(y-height, rightSide)+(rightSide ? -r : r), (rightSide ? -y : y)); }
else throw pointOut;
}
public Vector2 GetPoint(float p) {
if (p <= radWidth) {
return GetPointOnBase(p, true)+Vector2.right*r; }
else if (p > radWidth && p <= radWidth + radHeight) {
return GetPointOnLegs(p - radWidth, true)+Vector2.right*fullWidth; }
else if (p > radWidth + radHeight && p <= radWidth*2 + radHeight) {
return GetPointOnBase(p - (radWidth + radHeight), false)+Vector2.right*radWidth+Vector2.down*height;
} else if (p > radWidth*2 + radHeight && p <= radWidth*2 + radHeight*2) {
return GetPointOnLegs(p - (radWidth*2 + radHeight), false)+Vector2.down*height;
} else throw pointOut;
}
public Vector2 Interpolate(float t) => GetPoint(Mathf.Lerp(0f, perimeter, t));
c#
public RoundRect(float width, float height, float r) {
if (width < r || height < r) { throw new Exception("Radius"); }
this.width = width - 2*r;
this.height = height - 2*r;
this.r = r;
public float CornerByAxisPoint(float p, bool positive) {
if (Mathf.Abs(p) > 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), (topSide ? r : -r)); }
else 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(0, y * (rightSide ? -1 : 1)); }
else if (y > height) { return new Vector2(CornerByAxisPoint(y-height, rightSide)+(rightSide ? -r : r), (rightSide ? -y : y)); }
else throw pointOut;
}
public Vector2 GetPoint(float p) {
if (p <= radWidth) {
return GetPointOnBase(p, true)+Vector2.right*r; }
else if (p > radWidth && p <= radWidth + radHeight) {
return GetPointOnLegs(p - radWidth, true)+Vector2.right*fullWidth; }
else if (p > radWidth + radHeight && p <= radWidth*2 + radHeight) {
return GetPointOnBase(p - (radWidth + radHeight), false)+Vector2.right*radWidth+Vector2.down*height;
} else if (p > radWidth*2 + radHeight && p <= radWidth*2 + radHeight*2) {
return GetPointOnLegs(p - (radWidth*2 + radHeight), false)+Vector2.down*height;
} else throw pointOut;
}
public Vector2 Interpolate(float t) => GetPoint(Mathf.Lerp(0f, perimeter, t));
I'm making rounded rectangle. Either pieces are missing or lerp seems ignoring corners. Using unit circle x^2+y^2=r^2. Might be sqrt() or comparison conditions
No description
6 Replies
Omnissiah
Omnissiah2mo ago
is a } missing somewhere? is RoundRect a constructor?
lil☆
lil☆OP2mo ago
The code is working properly, the algorithm is not. RoundRect is a constructor, but the code i sent is not full because of the message length limit. The other methods i sent are full I sent the constructor to show how i define width and height Which is width without two radiuses And height is height without two radiuses I think the code is full enough to debug it if needed
Omnissiah
Omnissiah2mo ago
Interpolate doesn't look like it's ever called main method seems to be GetPoint but it's not shown how it's called, is it in a loop?
lil☆
lil☆OP2mo ago
I haven't brought the lines where I call the method, only the class itself Interpolate runs for every point I want to get I had a for loop. That goes by 0.01 up to 1 And that it used by GetPoint(Mathf.Lerp(0f, perimeter, t)); Which maps the point from 0 to perimeter
lil☆
lil☆OP2mo ago
Actually I have my stackoverflow question posted by now and I described that I assume that the method I was trying to implement was wrong inherently https://stackoverflow.com/questions/79080391/im-trying-to-implement-rounded-rectangles-that-can-be-used-with-interpolation
Stack Overflow
I'm trying to implement rounded rectangles that can be used with in...
public class RoundRect { float width; float height; float r; float fullWidth => width + r * 2; float fullHeight => height + r * 2; float radWid...
lil☆
lil☆OP2mo ago
Density of the points of one end of quarter arc of unit circle is different than density of the same points at the other end of the arc So i had more gaps I think it may be solved with angles and a new parameter for angle increment but I'm not sure I was just using axis coordinate increment, not angles I assume that was the reason but still not sure I actually wasn't using Interpolate for the first picture. It is
Visuals.RoundRect rect = new Visuals.RoundRect(0f,0f,1f,1f,0.1f,false);
for (float i = 0f; i < 10f; i += 0.01f) {
Vector2 point = rect.GetPoint(i);
GameObject obj = GameObject.Instantiate(test, Visuals.RoundRect.OnGround(point), Quaternion.identity);
obj.SetActive(true);
}
Visuals.RoundRect rect = new Visuals.RoundRect(0f,0f,1f,1f,0.1f,false);
for (float i = 0f; i < 10f; i += 0.01f) {
Vector2 point = rect.GetPoint(i);
GameObject obj = GameObject.Instantiate(test, Visuals.RoundRect.OnGround(point), Quaternion.identity);
obj.SetActive(true);
}
But i was calling Interpolate the same but with for (float i = 0f; i < 1f; i += 0.01f) { and it's the second picture But the thing is I think the gaps emerge not because of the way I do this for-loop but because it requires more density to cover other end of the quarters rather than equal interpolation. I may be wrong about this though Also what I want is not to draw a rectangle but to place objects equally on edges of rounded rectangle I'm rewriting it with a simple rectangle right now completely so it may work now because spreading points equally seems more complicated than just to interpolate perimeter but I'm not sure how to approach arcs yet
Want results from more Discord servers?
Add your server