Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package opengl.figures;
- public class CylinderLineIntersector {
- static class Point2D {
- double x, y;
- Point2D(double x, double y) {
- super();
- this.x = x;
- this.y = y;
- }
- double distanceTo(Point2D other) {
- double dx = this.x - other.x;
- double dy = this.y - other.y;
- return Math.sqrt(dx * dx + dy * dy);
- }
- }
- static class Point3D extends Point2D {
- double z;
- Point3D(double x, double y, double z) {
- super(x, y);
- this.z = z;
- }
- }
- private static class Vector3D extends Point3D {
- Vector3D(Point3D end) {
- this(end.x, end.y, end.z);
- }
- Vector3D(double x, double y, double z) {
- super(x, y, z);
- }
- Vector3D normalize() {
- double length = length();
- x /= length;
- y /= length;
- z /= length;
- return this;
- }
- double length() {
- return Math.sqrt(x * x + y * y + z * z);
- }
- Vector3D multiply(double k) {
- x *= k;
- y *= k;
- z *= k;
- return this;
- }
- Point3D applyTo(Point3D point) {
- return new Point3D(point.x + x, point.y + y, point.z + z);
- }
- }
- private static class Line3D {
- Point3D from, to;
- double a, b, c;
- Line3D(Point3D from, Point3D to) {
- this.from = from;
- this.to = to;
- /*
- * x = t * (x2 - x1) + x1
- * y = t * (y2 - y1) + y1
- * z = t * (z2 - z1) + z1
- */
- this.a = to.x - from.x;
- this.b = to.y - from.y;
- this.c = to.z - from.z;
- }
- private double getT(Point2D point) {
- if (a != 0) {
- return (point.x - from.x) / a;
- }
- if (b != 0) {
- return (point.y - from.y) / b;
- }
- return 0;
- }
- double getZ(Point2D point) {
- double t = getT(point);
- return c * t + from.z;
- }
- }
- private static class Line2D {
- double a, b, c;
- Line2D(Point2D from, Point2D to) {
- this.a = to.y - from.y;
- this.b = from.x - to.x;
- this.c = -a * from.x - b * from.y;
- double length = Math.sqrt(a * a + b * b);
- a /= length;
- b /= length;
- c /= length;
- }
- double distanceTo(Point2D point) {
- return Math.abs(a * point.x + b * point.y + c);
- }
- }
- public static boolean intersects(
- Point3D center, double radius, double height,
- Point3D from, Point3D to) {
- Vector3D moving = new Vector3D(center).multiply(-1);
- center = moving.applyTo(center);
- from = moving.applyTo(from);
- to = moving.applyTo(to);
- // now center of cylinder in (0, 0, 0)
- // edgecase - if line is vertical - so it looks as Point on circle
- if (from.x == to.x && from.y == to.y) {
- Point2D planeIntersection = new Point2D(from.x, from.y);
- return center.distanceTo(planeIntersection) <= radius;
- }
- Line2D line2D = new Line2D(from, to);
- double centerLineDistance = line2D.distanceTo(center);
- if (centerLineDistance > radius) return false;
- double otherTriangleSide = Math.sqrt(radius * radius - centerLineDistance * centerLineDistance);
- Vector3D lineNormal = new Vector3D(line2D.a, line2D.b, 0).normalize().multiply(centerLineDistance);
- Vector3D lineCollinear = new Vector3D(-line2D.b, line2D.a, 0).normalize().multiply(otherTriangleSide);
- Point3D middle = lineNormal.applyTo(center);
- Point3D first = lineCollinear.applyTo(middle);
- Point3D second = lineCollinear.multiply(-1).applyTo(middle);
- Line3D line3D = new Line3D(from, to);
- double z1 = line3D.getZ(first), z2 = line3D.getZ(second);
- if (z1 > z2) {
- double tmp = z1;
- z1 = z2;
- z2 = tmp;
- }
- double cylinderZ1 = -height / 2, cylinderZ2 = height / 2;
- // check intersection of two segments [z1; z2] and [cZ1; cZ2] on line
- return Math.max(z1, cylinderZ1) <= Math.min(z2, cylinderZ2);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement