discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Re: Calculate points in an arc

FH
Father Horton
Tue, Apr 5, 2022 9:16 PM

I'm not quite clear on what you're doing, but this looks more complicated
than need be.

Let's say one side is a horizontal line from point A to point B, and the
other side is a vertical line from point C to point D, and that B and C are
the two closest points.

Then, if the arc is a perfect semicircle, the center is (B.x, C.y) and the
radius is B.y - C.y (or C.x - B.x).

If the arc is not a perfect circle, then let X = C.x - B.x and Y = B.y -
C.y. You can produce an arc whose tangents match up perfectly to the
endpoints by constructing a circle with radius = min(X, Y) and then scaling
it. If X > Y then scale by (X/Y, 1), and if Y>X then scale by (1, Y/X).

On Mon, Apr 4, 2022 at 4:30 PM Jan Öhman via Discuss <
discuss@lists.openscad.org> wrote:

---------- Forwarded message ----------
From: "Jan Öhman" jan_ohman@yahoo.com
To: OpenSCAD General Discussion discuss@lists.openscad.org
Cc:
Bcc:
Date: Mon, 4 Apr 2022 21:30:27 +0000 (UTC)
Subject: [OpenSCAD] Calculate points in an arc
I have tried to make different calculations to put the rounded corners
together with a long bend.
I know the points where the long bend begins and where it ends, as well as
how high it should be.
but my calculations do not work

start (left)* x1=10.00, y1=49.25*
middle    x2 = 60.50, y2 = 51
end (right) x3 = 101, y3 = 49.25
First, I calculate the radius of an imaginary circle using the formula
below
The center of the virtual circle has the coordinates x0 and y0
[image: Infoga bild]

s = x3 - x1 91,00000000
h = y2 - y1 1,75000000
r = ((s^2) + (4h^2)) / (8h) 592,37500000
h = r - ( rot(4 * r^2 - s^2) / 2) 1,75000000
s = 2 * rot( h * (2*r - h)) 90,99038411
x0 = x2 60,50000000
y0 = y2 – r -541,37500000
Previously, I calculated the angles of the circle sector and used "my"
function to create the [x,y]-values for the arc. (but failed)
Either the arc did not reach the start and stop values or it ended up a
little too high or low.
(I have no idea why)

In this caset, I thought to create a table with the start value first and
the end value last.
Now I know x0, y0 and the r (radius) - from above and use this
formula .:
[image: Infoga bild]
Rewrites the formula so that it becomes a function of y
Step1 .: r² = (x - x0)² + (y – y0)²
Step2 .: (y - b)² = r² - (x – a)²
Step3 .: y = ROT(r² - (x - x0)²)+y0

Finally, I set the start value (x1), middle value(x2)
and the end value(x3)
and calculate the y values.

x = *y0 =      * desire difference
10 49,64766471 49,25 -0,397664708819093
60,5 51,49981502 51,5 0,00018497967755593
101 50,25505002 49,25 -1,00505001815964

(it was complicated to make the tables in the email)
I do not know why the calculated result differs from the desired value.
I think it's quite a lot - In the column on the far right - The center
point differed the least
(However, got better result than using angles)

What can be done to get an even better result?
[10, 49.25], [60.5, 51.5], [101, 49.25] (and many values between these)

Attach some code for possible test

$fa = 12;
$fs = 0.5;
fn = 50;
// y = 80-2000;
// points3 = circSect(0, 0, 2000, [0, 180], "left", 1, fn);
// points3 = circSect(0, 80-2000, 2000, [87, 93], "left", 1, 1000);
// points3 = circSect(55.5, 50.55-2000, 2000, [87.151, 92.826], "left", 1,
1000);
// polygon(points3);

p1x = 10;      // the start value
p1y = 49.25;
p2x = 60.50;      // the middle value
p2y = 51;
p3x = 101;      // the end value
p3y = p1y;

// http://matmin.kevius.com/cirkel.php
// r = ((s^2) + (4h^2)) / (8h)

s = p3x - p1x;  // 91
h = p2y - p1y;  // 1.25
radius = ((s^2) + (4h^2)) / (8h); // 828.725
echo(s, s^2, h, 4h^2, 8h, radius);
echo("");

// http://www.rasmus.is/sv/t/G/su30k3.html
// deg = degrade( sin( a / radius ));
deg1 = asin( (s/2) / radius );  // 3.14733
deg2 = deg1*2;                  // 6.29466
echo( deg1, deg2 );
echo("");

// frDeg = 90-30;
// toDeg = 90+30;
frDeg = 90-deg1;  // 3.8183 (3.872)
toDeg = 90+deg1;  // (4)
xPos = 55;
yPos = 51.5-radius;  // 50.79

points0 = circSect(  xPos, yPos, radius, [frDeg, toDeg], "left", 1, 4000);
// Hörn nere till vänster
polygon(points0);

//points1 = circSect(  10, 11.25,  10, [0, 90], "bottom", 1, fn); // Hörn
nere till vänster

points2 = circSect(  10, 39.25,  10, [0, 90], "left",  1, 100); // Hörn
uppe till vänster

points3 = circSect( 101, 39.25,  10, [0, 90], "top",    1, 100); // Hörn
uppe till höger

//points4 = circSect( 101, 11.25,  10, [0, 90], "right",  1, fn); // Hörn
nere till höger

echo(points2) // [0,39.25]  - [10, 49.25]
echo("");
echo(points0) // [9.5, 50.25] - [97.9774, 50.3849]
echo("");
echo(points3)

color("cyan"){
polygon(points0);
// polygon(points1);

polygon(points2);
polygon(points3);
// polygon(points4);

// polygon(concat(points2, points0, points3));
};

// polygon(concat(points1, points2, points3, points4));

// https://openhome.cc/eGossip/OpenSCAD/SectorArc.html
function circSect(x=0, y=0, radius=10, angles=[0,270], startRef="bottom",
rotate=1, fn=24)  =
let(
startAngel  = (startRef == "left")  ?  0
: (startRef == "bottom") ?  90
: (startRef == "right")  ? 180
: (startRef == "top")    ? 270
: undef,
r = radius,
//r = radius / cos(180 / fn),
step = 360 / fn,
// points = [[x, y],
points = [
for(a = [angles[0]-startAngel : step : angles[1]-startAngel])
[-rotate * r * cos(a)+x, r * sin(a)+y]]
) points;

---------- Forwarded message ----------
From: "Jan Öhman via Discuss" discuss@lists.openscad.org
To: OpenSCAD General Discussion discuss@lists.openscad.org
Cc: "Jan Öhman" jan_ohman@yahoo.com
Bcc:
Date: Mon, 4 Apr 2022 21:30:27 +0000 (UTC)
Subject: [OpenSCAD] Calculate points in an arc


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I'm not quite clear on what you're doing, but this looks more complicated than need be. Let's say one side is a horizontal line from point A to point B, and the other side is a vertical line from point C to point D, and that B and C are the two closest points. Then, if the arc is a perfect semicircle, the center is (B.x, C.y) and the radius is B.y - C.y (or C.x - B.x). If the arc is not a perfect circle, then let X = C.x - B.x and Y = B.y - C.y. You can produce an arc whose tangents match up perfectly to the endpoints by constructing a circle with radius = min(X, Y) and then scaling it. If X > Y then scale by (X/Y, 1), and if Y>X then scale by (1, Y/X). On Mon, Apr 4, 2022 at 4:30 PM Jan Öhman via Discuss < discuss@lists.openscad.org> wrote: > > > > ---------- Forwarded message ---------- > From: "Jan Öhman" <jan_ohman@yahoo.com> > To: OpenSCAD General Discussion <discuss@lists.openscad.org> > Cc: > Bcc: > Date: Mon, 4 Apr 2022 21:30:27 +0000 (UTC) > Subject: [OpenSCAD] Calculate points in an arc > I have tried to make different calculations to put the rounded corners > together with a long bend. > I know the points where the long bend begins and where it ends, as well as > how high it should be. > but my calculations do not work > > start (left)* x1=10.00, y1=49.25* > middle *x2 = 60.50, y2 = 51* > end (right) *x3 = 101, y3 = 49.25* > First, I calculate the radius of an imaginary circle using the formula > below > The center of the virtual circle has the coordinates *x0* and *y0* > [image: Infoga bild] > > > > *s =* x3 - x1 91,00000000 > *h =* y2 - y1 1,75000000 > *r =* ((s^2) + (4*h^2)) / (8*h) 592,37500000 > *h =* r - ( rot(4 * r^2 - s^2) / 2) 1,75000000 > *s =* 2 * rot( h * (2*r - h)) 90,99038411 > *x0 =* x2 60,50000000 > *y0 =* y2 – r -541,37500000 > Previously, I calculated the angles of the circle sector and used "my" > function to create the [x,y]-values for the arc. (but failed) > Either the arc did not reach the start and stop values or it ended up a > little too high or low. > (I have no idea why) > > In this caset, I thought to create a table with the start value first and > the end value last. > Now I know *x0, y0* and the *r* (radius) - from above and use this > formula .: > [image: Infoga bild] > Rewrites the formula so that it becomes a function of y > Step1 .: r² = (x - x0)² + (y – y0)² > Step2 .: (y - b)² = r² - (x – a)² > Step3 .: y = ROT(r² - (x - x0)²)+y0 > > Finally, I set the start value (x1), middle value(x2) > and the end value(x3) > and calculate the y values. > > *x =* *y0 = * desire difference > 10 49,64766471 49,25 -0,397664708819093 > 60,5 51,49981502 51,5 0,00018497967755593 > 101 50,25505002 49,25 -1,00505001815964 > > (it was complicated to make the tables in the email) > I do not know why the calculated result differs from the desired value. > I think it's quite a lot - In the column on the far right - The center > point differed the least > (However, got better result than using angles) > > What can be done to get an even better result? > *[10, 49.25], [60.5, 51.5], [101, 49.25]* (and many values between these) > > Attach some code for possible test > > $fa = 12; > $fs = 0.5; > fn = 50; > // y = 80-2000; > // points3 = circSect(0, 0, 2000, [0, 180], "left", 1, fn); > // points3 = circSect(0, 80-2000, 2000, [87, 93], "left", 1, 1000); > // points3 = circSect(55.5, 50.55-2000, 2000, [87.151, 92.826], "left", 1, > 1000); > // polygon(points3); > > > p1x = 10; // the start value > p1y = 49.25; > p2x = 60.50; // the middle value > p2y = 51; > p3x = 101; // the end value > p3y = p1y; > > // http://matmin.kevius.com/cirkel.php > // r = ((s^2) + (4*h^2)) / (8*h) > > s = p3x - p1x; // 91 > h = p2y - p1y; // 1.25 > radius = ((s^2) + (4*h^2)) / (8*h); // 828.725 > echo(s, s^2, h, 4*h^2, 8*h, radius); > echo(""); > > // http://www.rasmus.is/sv/t/G/su30k3.html > // deg = degrade( sin( a / radius )); > deg1 = asin( (s/2) / radius ); // 3.14733 > deg2 = deg1*2; // 6.29466 > echo( deg1, deg2 ); > echo(""); > > // frDeg = 90-30; > // toDeg = 90+30; > frDeg = 90-deg1; // 3.8183 (3.872) > toDeg = 90+deg1; // (4) > xPos = 55; > yPos = 51.5-radius; // 50.79 > > points0 = circSect( xPos, yPos, radius, [frDeg, toDeg], "left", 1, 4000); > // Hörn nere till vänster > polygon(points0); > > > > //points1 = circSect( 10, 11.25, 10, [0, 90], "bottom", 1, fn); // Hörn > nere till vänster > > points2 = circSect( 10, 39.25, 10, [0, 90], "left", 1, 100); // Hörn > uppe till vänster > > points3 = circSect( 101, 39.25, 10, [0, 90], "top", 1, 100); // Hörn > uppe till höger > > //points4 = circSect( 101, 11.25, 10, [0, 90], "right", 1, fn); // Hörn > nere till höger > > echo(points2) // [0,39.25] - [10, 49.25] > echo(""); > echo(points0) // [9.5, 50.25] - [97.9774, 50.3849] > echo(""); > echo(points3) > > color("cyan"){ > polygon(points0); > // polygon(points1); > > polygon(points2); > polygon(points3); > // polygon(points4); > > // polygon(concat(points2, points0, points3)); > }; > > > // polygon(concat(points1, points2, points3, points4)); > > > > // https://openhome.cc/eGossip/OpenSCAD/SectorArc.html > function circSect(x=0, y=0, radius=10, angles=[0,270], startRef="bottom", > rotate=1, fn=24) = > let( > startAngel = (startRef == "left") ? 0 > : (startRef == "bottom") ? 90 > : (startRef == "right") ? 180 > : (startRef == "top") ? 270 > : undef, > r = radius, > //r = radius / cos(180 / fn), > step = 360 / fn, > // points = [[x, y], > points = [ > for(a = [angles[0]-startAngel : step : angles[1]-startAngel]) > [-rotate * r * cos(a)+x, r * sin(a)+y]] > ) points; > > > > > ---------- Forwarded message ---------- > From: "Jan Öhman via Discuss" <discuss@lists.openscad.org> > To: OpenSCAD General Discussion <discuss@lists.openscad.org> > Cc: "Jan Öhman" <jan_ohman@yahoo.com> > Bcc: > Date: Mon, 4 Apr 2022 21:30:27 +0000 (UTC) > Subject: [OpenSCAD] Calculate points in an arc > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >