Skip to content

Instantly share code, notes, and snippets.

@mattneary
Last active August 29, 2015 14:03
Show Gist options
  • Save mattneary/8454f61ac9b562f0fcc1 to your computer and use it in GitHub Desktop.
Save mattneary/8454f61ac9b562f0fcc1 to your computer and use it in GitHub Desktop.
Bezier surface intersection with a plane.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Kiss.Effigy.code {
public class ClsSensorPlaneIntersector {
public Vector Origin;
public Func<float, float, Vector> Parametric;
public float Plane;
public float Epsilon = 0.01f;
public ClsSensorPlaneIntersector(Vector origin, Func<float, float, Vector> parametric, float elevation) {
// The first argument is the position of the region's origin.
// The second argument is a parametric function of two variables:
// - the first float is an angle, in radians, of rotation.
// - the second float is the height parameter, ranging from 0 to 1.
// The third argument is an elevation of intersection.
Origin = origin;
Parametric = parametric;
Plane = elevation;
}
public Boolean FuzzyEqual(float a, float b) {
return Math.Abs(a - b) <= Epsilon;
}
public Boolean FloatInRange(float x, float a, float b) {
return (a < x && b > x) || (a > x && b < x);
}
public Vector FindPointIntersection(Vector origin, Func<float, Vector> surfaceSlice, float elevation, float min, float max) {
var minE = (float)surfaceSlice(min).k;
var maxE = (float)surfaceSlice(max).k;
var mid = (max + min) / 2;
var midE = (float)surfaceSlice(mid).k;
if (FuzzyEqual(elevation, midE) || FuzzyEqual(mid, max)) {
// If a point was found that is sufficiently close to the place, or
// if the range has been drilled down to a sufficiently small span,
// return the point of focus.
return surfaceSlice(mid);
}
if (FloatInRange(elevation, minE, midE)) {
return FindPointIntersection(origin, surfaceSlice, elevation, min, mid);
} else if(FloatInRange(elevation, midE, maxE)) {
return FindPointIntersection(origin, surfaceSlice, elevation, mid, max);
} else {
throw new Exception("Could not intersect");
return null;
}
}
public List<Vector> Intersect() {
var precision = 20;
var intersections = new List<Vector>();
for (var theta = 0f; theta <= Math.PI * 2; theta += ((float)Math.PI / precision)) {
Func<float, Vector> slice = (float h) => { return Parametric(theta, h); };
var intersection = FindPointIntersection(Origin, slice, Plane, 0f, 1f);
intersections.Add(intersection);
}
return intersections;
}
}
}
Func<float, float, Vector> surface = (float theta, float h) => {
    var hp = (h - 0.5f) * 2;
    var R = 10f;
    var r = Math.Sqrt(R*R - hp*hp);
    return new Vector(
        r * Math.Cos(theta),
        r * Math.Sin(theta),
        hp);
};
var placeIntersector = new ClsSensorPlaneIntersector(new Vector(0, 0, 0), surface, -1f);
var ps = placeIntersector.Intersect();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment