Skip to content

Commit b843a5f

Browse files
committed
Add bezier curves
1 parent ea978d9 commit b843a5f

File tree

1 file changed

+55
-48
lines changed

1 file changed

+55
-48
lines changed

src/main/kotlin/imgui/draw.kt

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,14 @@ class DrawList(sharedData: DrawListSharedData?) {
745745
_vtxCurrentIdx += vtxCount
746746
}
747747
}
748-
// IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0);
748+
749+
fun addBezierCurve(pos0: Vec2, cp0: Vec2, cp1: Vec2, pos1: Vec2, col: Int, thickness: Float, numSegments: Int = 0) {
750+
if (col hasnt COL32_A_MASK) return
751+
752+
pathLineTo(pos0)
753+
pathBezierCurveTo(cp0, cp1, pos1, numSegments)
754+
pathStroke(col, false, thickness)
755+
}
749756

750757

751758
// -----------------------------------------------------------------------------------------------------------------
@@ -792,53 +799,53 @@ class DrawList(sharedData: DrawListSharedData?) {
792799
}
793800
}
794801

795-
// fun pathBezierCurveTo(p1: Vec2, p2: Vec2, p3: Vec2, numSegments: Int = 0) {
796-
//
797-
// val p1 = _path.last()
798-
// if (numSegments == 0)
799-
// // Auto-tessellated
800-
// pathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->style.CurveTessellationTol, 0)
801-
// else
802-
// {
803-
// float t_step = 1.0f / (float)num_segments;
804-
// for (int i_step = 1; i_step <= num_segments; i_step++)
805-
// {
806-
// float t = t_step * i_step;
807-
// float u = 1.0f - t;
808-
// float w1 = u*u*u;
809-
// float w2 = 3*u*u*t;
810-
// float w3 = 3*u*t*t;
811-
// float w4 = t*t*t;
812-
// _Path.push_back(ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y));
813-
// }
814-
// }
815-
// }
816-
//
817-
// private fun pathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
818-
// {
819-
// float dx = x4 - x1;
820-
// float dy = y4 - y1;
821-
// float d2 = ((x2 - x4) * dy - (y2 - y4) * dx);
822-
// float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
823-
// d2 = (d2 >= 0) ? d2 : -d2;
824-
// d3 = (d3 >= 0) ? d3 : -d3;
825-
// if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy))
826-
// {
827-
// path->push_back(ImVec2(x4, y4));
828-
// }
829-
// else if (level < 10)
830-
// {
831-
// float x12 = (x1+x2)*0.5f, y12 = (y1+y2)*0.5f;
832-
// float x23 = (x2+x3)*0.5f, y23 = (y2+y3)*0.5f;
833-
// float x34 = (x3+x4)*0.5f, y34 = (y3+y4)*0.5f;
834-
// float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f;
835-
// float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f;
836-
// float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f;
837-
//
838-
// PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1);
839-
// PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1);
840-
// }
841-
// }
802+
fun pathBezierCurveTo(p2: Vec2, p3: Vec2, p4: Vec2, numSegments: Int = 0) {
803+
804+
val p1 = _path.last()
805+
if (numSegments == 0)
806+
// Auto-tessellated
807+
pathBezierToCasteljau(_path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, ImGui.style.curveTessellationTol, 0)
808+
else {
809+
val t_step = 1.0f / numSegments.f
810+
for (i_step in 1 until numSegments + 1) {
811+
val t = t_step * i_step
812+
val u = 1.0f - t
813+
val w1 = u * u * u
814+
val w2 = 3 * u * u * t
815+
val w3 = 3 * u * t * t
816+
val w4 = t * t * t
817+
_path.add(Vec2(w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x, w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y))
818+
}
819+
}
820+
}
821+
822+
private fun pathBezierToCasteljau(path: ArrayList<Vec2>, x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float, x4: Float, y4: Float, tess_tol: Float, level: Int) {
823+
val dx = x4 - x1
824+
val dy = y4 - y1
825+
var d2 = ((x2 - x4) * dy - (y2 - y4) * dx)
826+
var d3 = ((x3 - x4) * dy - (y3 - y4) * dx)
827+
d2 = if (d2 >= 0) d2 else -d2
828+
d3 = if (d3 >= 0) d3 else -d3
829+
if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy)) {
830+
path.add(Vec2(x4, y4))
831+
} else if (level < 10) {
832+
val x12 = (x1 + x2) * 0.5f
833+
val y12 = (y1 + y2) * 0.5f
834+
val x23 = (x2 + x3) * 0.5f
835+
val y23 = (y2 + y3) * 0.5f
836+
val x34 = (x3 + x4) * 0.5f
837+
val y34 = (y3 + y4) * 0.5f
838+
val x123 = (x12 + x23) * 0.5f
839+
val y123 = (y12 + y23) * 0.5f
840+
val x234 = (x23 + x34) * 0.5f
841+
val y234 = (y23 + y34) * 0.5f
842+
val x1234 = (x123 + x234) * 0.5f
843+
val y1234 = (y123 + y234) * 0.5f
844+
845+
pathBezierToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1)
846+
pathBezierToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1)
847+
}
848+
}
842849

843850
fun pathRect(a: Vec2, b: Vec2, rounding_: Float = 0f, roundingCorners: Int = Dcf.All.i) {
844851

0 commit comments

Comments
 (0)