Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate middle point of Bezier Curve

Tags:

c#

wpf

bezier

point

I have a function to draw Bezier Curve through three points. I have already 2 points (start and end) - A and B. How do I calculate middle point between those two points as middle point would be always a little higher or lower than linear function of those two points.

Example:

enter image description here

Any formulas, ideas would be great!

like image 427
morad1n Avatar asked May 11 '14 19:05

morad1n


2 Answers

I think this is what you're looking for:

http://blog.sklambert.com/finding-the-control-points-of-a-bezier-curve/

It goes into detail on calculating the various points on a Bezier curve.

You may also be interested in this more specific example for your application:

http://www.codeproject.com/Articles/223159/Midpoint-Algorithm-Divide-and-Conquer-Method-for-D

If you really want to get into it, then I suggest this Primer:

http://pomax.github.io/bezierinfo/

Bezier curves are a bit more complicated than simple arcs. For an arc, you can just use this formula:

R = H/2 + W^2/8H

...which definitely won't work for a Bezier curve. On a Quadratic Bezier curve, for example, to calculate a point, you must use:

enter image description here

Sources: http://en.wikipedia.org/wiki/B%C3%A9zier_curve, Quadratic Bezier Curve: Calculate Point

like image 157
B.K. Avatar answered Sep 20 '22 11:09

B.K.


Below is what I use to get the control point of a quad bezier curve. It should work for your problem where the control point is on the curve. It's in Swift but you should be able to convert it to another language easily. Basically at the midpoint of the line (whose points are point1 and point2) I work out a perpendicular line with the given length. Clockwise parameter determines which side of the line the point should fall on.

func getControlPointWithPoint1(point1:CGPoint, point2:CGPoint, length:CGFloat, clockwise:Bool) -> CGPoint {
  let angle = getAngleWithPoint1(point1, point2:point2)
  let direction = clockwise ? 1 : -1
  let perpendicularAngle = angle + (CGFloat(direction) * CGFloat((M_PI / 2)))
  let midPoint = getMidPointWithPoint1(point1, point2:point2)
  return CGPointMake(midPoint.x + (cos(perpendicularAngle) * length), midPoint.y + (sin(perpendicularAngle) * length))
}

func getAngleWithPoint1(point1:CGPoint, point2:CGPoint) -> CGFloat {
  return atan2((point2.y - point1.y), (point2.x - point1.x))
}

func getMidPointWithPoint1(point1:CGPoint, point2:CGPoint) -> CGPoint {
  return CGPointMake((point1.x + point2.x) / 2, (point1.y + point2.y) / 2)
}

Below is how it would map to your diagram letters:

c = getControlPointWithPoint1(a, point2:b, length:h, clockwise:true)
like image 34
Mark Horgan Avatar answered Sep 18 '22 11:09

Mark Horgan