Download src/Mod/CAM/libarea/Arc.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 3.42 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/libarea/Arc.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/CAM/libarea/Arc.cpp
-
curl -L -o Arc.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/libarea/Arc.cpp
3.42 kB
| // SPDX-License-Identifier: BSD-3-Clause | |
| // Arc.cpp | |
| // Copyright 2011, Dan Heeks | |
| // This program is released under the BSD license. See the file COPYING for details. | |
| void CArc::SetDirWithPoint(const Point& p) | |
| { | |
| double angs = atan2(m_s.y - m_c.y, m_s.x - m_c.x); | |
| double ange = atan2(m_e.y - m_c.y, m_e.x - m_c.x); | |
| double angp = atan2(p.y - m_c.y, p.x - m_c.x); | |
| if (ange < angs) { | |
| ange += 6.2831853071795864; | |
| } | |
| if (angp < angs - 0.0000000000001) { | |
| angp += 6.2831853071795864; | |
| } | |
| if (angp > ange + 0.0000000000001) { | |
| m_dir = false; | |
| } | |
| else { | |
| m_dir = true; | |
| } | |
| } | |
| double CArc::IncludedAngle() const | |
| { | |
| double angs = atan2(m_s.y - m_c.y, m_s.x - m_c.x); | |
| double ange = atan2(m_e.y - m_c.y, m_e.x - m_c.x); | |
| if (m_dir) { | |
| // make sure ange > angs | |
| if (ange < angs) { | |
| ange += 6.2831853071795864; | |
| } | |
| } | |
| else { | |
| // make sure angs > ange | |
| if (angs < ange) { | |
| angs += 6.2831853071795864; | |
| } | |
| } | |
| return fabs(ange - angs); | |
| } | |
| bool CArc::AlmostALine() const | |
| { | |
| Point mid_point = MidParam(0.5); | |
| if (Line(m_s, m_e - m_s).Dist(mid_point) <= Point::tolerance) { | |
| return true; | |
| } | |
| const double max_arc_radius = 1.0 / Point::tolerance; | |
| double radius = m_c.dist(m_s); | |
| if (radius > max_arc_radius) { | |
| return true; // We don't want to produce an arc whose radius is too large. | |
| } | |
| return false; | |
| } | |
| Point CArc::MidParam(double param) const | |
| { | |
| /// returns a point which is 0-1 along arc | |
| if (fabs(param) < 0.00000000000001) { | |
| return m_s; | |
| } | |
| if (fabs(param - 1.0) < 0.00000000000001) { | |
| return m_e; | |
| } | |
| Point p; | |
| Point v = m_s - m_c; | |
| v.Rotate(param * IncludedAngle()); | |
| p = v + m_c; | |
| return p; | |
| } | |
| // segments - number of segments per full revolution! | |
| // d_angle - determines the direction and the amount of the arc to draw | |
| void CArc::GetSegments(void (*callbackfunc)(const double* p), double pixels_per_mm) const | |
| { | |
| if (m_s == m_e) { | |
| return; | |
| } | |
| Point Va = m_s - m_c; | |
| Point Vb = m_e - m_c; | |
| double start_angle = atan2(Va.y, Va.x); | |
| double end_angle = atan2(Vb.y, Vb.x); | |
| if (m_dir) { | |
| if (start_angle > end_angle) { | |
| end_angle += 6.28318530717958; | |
| } | |
| } | |
| else { | |
| if (start_angle < end_angle) { | |
| end_angle -= 6.28318530717958; | |
| } | |
| } | |
| double radius = m_c.dist(m_s); | |
| double d_angle = end_angle - start_angle; | |
| int segments = (int)(fabs(pixels_per_mm * radius * d_angle / 6.28318530717958 + 1)); | |
| double theta = d_angle / (double)segments; | |
| while (theta > 1.0) { | |
| segments *= 2; | |
| theta = d_angle / (double)segments; | |
| } | |
| double tangential_factor = tan(theta); | |
| double radial_factor = 1 - cos(theta); | |
| double x = radius * cos(start_angle); | |
| double y = radius * sin(start_angle); | |
| double pp[3] = {0.0, 0.0, 0.0}; | |
| for (int i = 0; i < segments + 1; i++) { | |
| Point p = m_c + Point(x, y); | |
| pp[0] = p.x; | |
| pp[1] = p.y; | |
| (*callbackfunc)(pp); | |
| double tx = -y; | |
| double ty = x; | |
| x += tx * tangential_factor; | |
| y += ty * tangential_factor; | |
| double rx = -x; | |
| double ry = -y; | |
| x += rx * radial_factor; | |
| y += ry * radial_factor; | |
| } | |
| } | |