# Figuring out \`arcTo()\`

**URL:** <https://openrndr.discourse.group/t/figuring-out-arcto/478>\
**Category:** Tutorials\
**Created:** [December 27, 2022, 7:20pm UTC](https://openrndr.discourse.group/t/figuring-out-arcto/478 "2022-12-27T19:20:04Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [December 27, 2022, 7:20pm UTC](https://openrndr.discourse.group/t/figuring-out-arcto/478/1 "2022-12-27T19:20:04Z")

</div>

![arcTo](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/5739169d5318a3c6b0f109310e82bd983121bc9d.png)

I was having some difficulties understanding the `contour { ... arcTo }` method, so I wrote this helper program which uses a GUI to change the arc parameters:

```auto
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.gui.GUI
import org.openrndr.extra.parameters.BooleanParameter
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.shape.contour

fun main() = application {
    configure { }
    program {
        val gui = GUI()
        val conf = @Description("Arc") object {
            @DoubleParameter("crx", 0.0, 640.0, order = 5)
            var crx = 0.0

            @DoubleParameter("cry", 0.0, 480.0, order = 10)
            var cry = 0.0

            @DoubleParameter("angle", -180.0, 180.0, order = 15)
            var angle = 0.0

            @BooleanParameter("largeArcFlag", order = 20)
            var largeArcFlag = true

            @BooleanParameter("sweepFlag", order = 25)
            var sweepFlag = true

            @DoubleParameter("tx", 0.0, 640.0, order = 30)
            var tx = 0.0

            @DoubleParameter("ty", 0.0, 480.0, order = 35)
            var ty = 0.0
        }
        extend(gui) {
            compartmentsCollapsedByDefault = false
            add(conf)
        }
        extend {
            drawer.clear(ColorRGBa.WHITE)
            drawer.contour(
                contour {
                    moveTo(drawer.bounds.center)
                    arcTo(conf.crx, conf.cry, conf.angle, conf.largeArcFlag, conf.sweepFlag, conf.tx, conf.ty)
                }
            )
        }
    }
}

```

The `arcTo` method is based on [this code](https://github.com/BigBadaboom/androidsvg/blob/f4b4ae246b8963d22f4c252d3175296ee2d88fbb/androidsvg/src/main/java/com/caverock/androidsvg/utils/SVGAndroidRenderer.java#L2912).

I realized that in my case I always want `crx` to be equal to `cry`. In that case `angle` seems to have no effect.

I’ll share a function to draw an arc with a `center`, a `start` point and an `end` point soon.

---

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [December 28, 2022, 12:06pm UTC](https://openrndr.discourse.group/t/figuring-out-arcto/478/2 "2022-12-28T12:06:13Z")

</div>

## `arcFromCenter`

```auto
/**
 * Create a [ShapeContour] arc specifying the [center],
 * [start] point and [end] point.
 *
 * The distance from [center] to both [start] and [end] must be equal,
 * otherwise an empty contour is returned.
 */
fun arcFromCenter(center: Vector2, start: Vector2, end: Vector2) =
    if (center.squaredDistanceTo(start) != center.squaredDistanceTo(end))
        ShapeContour.EMPTY
    else
        contour {
            val d = center.distanceTo(start)
            val side = ((start.x - center.x) * (end.y - center.y) -
                    (start.y - center.y) * (end.x - center.x)) > 0

            moveTo(start)
            arcTo(d, d, 0.0, !side, true, end)
        }

```

### Usage

 ![apps.simpleTests.ArcFromCenter-2022-12-28-13.05.06](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/ddf57ac06969f2b3a16c592a9e092efb55fc3a5c.png)

```auto
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.color.ColorXSVa
import org.openrndr.shape.Rectangle

fun main() = application {
    program {
        val center = drawer.bounds.center
        val rect = Rectangle.fromCenter(center, 200.0).contour
        val arcs = rect.segments.map {
            // create an arc for each segment of a square
            arcFromCenter(it.position(0.5), it.start, it.end).close()
        }
        extend {
            drawer.clear(ColorRGBa.WHITE)
            drawer.fill = null
            drawer.contour(rect)
            arcs.forEachIndexed { i, arc ->
                drawer.fill = ColorXSVa(i * 90.0, 0.5, 1.0).toRGBa()
                drawer.contour(arc)
            }
        }
    }
}

```
