This looks like a different problem to me, with some additional constraints on the tangents of the curve at the endpoints.
The blue lines would be the line segments I want, the black lines are where each line segment starts/ends, and the yellow circle is pretty much a guide for where I expect the line segments to roughly lie. Notice how the brown lines dont impact the yellow circles, the red dots are not related to anything but themselves
If the rotation of the endpoints doesn’t matter, and in fact, finding what “rotation” the endpoints have is exactly part of the problem, then we need a lot more information on what exactly the input dataset looks like to be able to solve the problem.
Note: I also think that exactly equal angles ("the smoothest possible arc) is not actually what the OP wants, but rather, tangency at the endpoints. Having a sharp node at one of the endpoints wouldn’t be very “smooth” after all. And if you do want both endpoints to be tangent then at least for the kind of shallow curve that OP posted, a cubic spline with both control points placed about half of the total distance between the points away from the endpoints is going to be pretty close to that “smoothest possible” curve while maintaining the tangency at the endpoints.
Edit: I see that you beat me to the punch offering an explanation, taking a look at it now.
Yes, my mistake for not offering more data or my own ideas on how to solve it(the circle chord thing). The smoothness would be based on the amount of line segments.
So, I’m still not really clear. What is the actual input data?
Just those red points isn’t enough information to know how big the yellow circles are supposed to be… how is their size defined?
function findPoints(Point1, Point2, amountOfSegments, lineLength)
return {} – x amount of points
end
Basically. I think I’m right in saying that’s all the necessary data to determine the points along the circle.
That still isn’t actually enough information, because there are two circles that will satisfy it:
Also, minor clarification, is the lineLength the length of each segment, or the length of the total arc?
lineLength would be what each line segment’s length is. It’s all equal.
You’re right about there being two perfect arcs for it, I was actually gonna let the user choose which arc they want, or base it off their camera’s point of view. So a simple 1/-1 to determine either curve would be good.
Oh, this is user-determined… are you sure that you don’t actually want the user to enter a third point to define the circle? Three points will uniquely determine a circle’s position and size without any other information.
I’d rather base it on a mouse’s/camera’s position/scroll wheel, it would be more user friendly than having to place three points down I feel.
I feel like this would be painful to solve algebraically (cannot easily derive arc length, and even if you have that, deriving radius from arc + cord length is also painful), but it is very easy to approximate it very accurately by doing a “binary search” for the circle’s radius, finding the radius for which the resulting segment length would be very close to the desired segment length.
I solved this issue with a rather unorthodox method. I used verlet integration.
I connected the lines in between edges and pushed each point outwards from the total center of the system. I then pushed it outwards from the starting points’ center.
Which gave results that I wanted.
Time Taken: 0.08189058303833
Distance differences of edges:
-0.002439022064209
-0.0020318031311035
-0.0014891624450684
-0.00096511840820313
-0.00052976608276367
-0.0001983642578125
4.1484832763672e-05
0.00017690658569336
0.00022459030151367
0.00022172927856445
0.00019073486328125
0.00013399124145508
7.7247619628906e-05
1.0967254638672e-05
-1.4305114746094e-06
1.1920928955078e-05
The distance difference can be made less with a bit more computation.
It works fine, it’s a bit oval and not perfect but it gets the job done and it’s hardly noticable.
You would be correct, I’m pretty sure that there is no exact algebraic solution given the setup requested. I arrived at the following algebraic expression for the radius (L is the distance between the two points, S is the segment length):
arctan(L / 2r) = n*arcsin(S / 2r)
[Edit: this was slightly wrong, both should be arcsin, and I need to consider the obtuse and acute cases of the solution. It’s still not solvable for an exact solution even when corrected though]
Now, my trigonometric identity voodoo isn’t particularly strong but that doesn’t feel like it has an algebraic solution thanks to the n*
part.
@Alkan You fine with an binary search solution using that formula or would you rather have an exact algebraic one where you specify the arc length instead? It should be really cheap to solve, performance wouldn’t be an issue: Solving a formula like that with binary search only takes a couple dozen iterations to get almost perfect accuracy.
Solved the problem. That took more effort than I expected to get working just right given that the algebraic solution is slightly different for the “convex” and “concave” cases. I give you, the solution for 10,000 segments spaced equally 2 studs apart given the endpoints with no visible error:
Code is still in the same place as before, updated. I put some IntValues underneath the script for the segment count and length that update it on changed so that you can play with it and verify that it works right. The script always uses the same chirality for it’s solution with respect to the inputs, so you can simply reverse the order of the position parameters to switch which “side” of the two possible options is solved for.
EDIT: Actually, something’s not quite right with my boundary conditions yet, let me check this again.
That’s amazing. What number would I swap out to generate the curve in the other possible solution though?
Join this group, or make a t-shirt for 7150 robux and I’ll buy it
Joined the group. Also, updated the code. It should actually work for real this time for both the convex and concave cases.
To switch which solution just reverse the parameter order:
divideArc(a, b, segmentCount, segmentLength) --> First solution
divideArc(b, a, segmentCount, segmentLength) --> Second solution
Since it’s consistent in which “side” it solves for given the parameters (it always draws the circle clockwise starting at the first input point ending at the second input point), switching the parameter order has the effect of reversing what side it solves for.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.