|
|
|
@ -47,13 +47,31 @@ pub struct RouteCCC {
|
|
|
|
pub end: Circle,
|
|
|
|
pub end: Circle,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// right straight right route
|
|
|
|
/// right straight right route
|
|
|
|
pub fn rsr(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
pub fn rsr(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
start: CircleRoute { circle: Circle { center: Point {x: end.magnitude, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
start: CircleRoute {
|
|
|
|
tangent: Vector { origin: Point { x: 0.0, y: 0.0 }, angle: 0.0, magnitude: 0.0},
|
|
|
|
circle: Circle {
|
|
|
|
end: CircleRoute { circle: Circle { center: Point {x: 0.0, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
center: Point {
|
|
|
|
|
|
|
|
x: end.magnitude,
|
|
|
|
|
|
|
|
y: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
tangent: Vector {
|
|
|
|
|
|
|
|
origin: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
magnitude: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
end: CircleRoute {
|
|
|
|
|
|
|
|
circle: Circle {
|
|
|
|
|
|
|
|
center: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
@ -62,36 +80,48 @@ pub fn rsr(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
// the angle has to be counter clockwise though (thats why 360 - end.angle)
|
|
|
|
// the angle has to be counter clockwise though (thats why 360 - end.angle)
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
x: end.origin.x + end.magnitude * (360.0 - end.angle).to_radians().cos(),
|
|
|
|
x: end.origin.x + end.magnitude * (360.0 - end.angle).to_radians().cos(),
|
|
|
|
y: end.origin.y + end.magnitude * (360.0 - end.angle).to_radians().sin()
|
|
|
|
y: end.origin.y + end.magnitude * (360.0 - end.angle).to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent pitch which is the same as the pitch between the two
|
|
|
|
// get the tangent pitch which is the same as the pitch between the two
|
|
|
|
// circle centers since our circles have the same radius
|
|
|
|
// circle centers since our circles have the same radius
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - route_csc.start.circle.center.y) /
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - route_csc.start.circle.center.y)
|
|
|
|
(route_csc.end.circle.center.x - route_csc.start.circle.center.x)).atan().to_degrees();
|
|
|
|
/ (route_csc.end.circle.center.x - route_csc.start.circle.center.x))
|
|
|
|
|
|
|
|
.atan()
|
|
|
|
|
|
|
|
.to_degrees();
|
|
|
|
|
|
|
|
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// start circle center x value
|
|
|
|
// start circle center x value
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x { route_csc.tangent.angle += 180.0; }
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x {
|
|
|
|
|
|
|
|
route_csc.tangent.angle += 180.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent magnitude this, again, is the same as the distance
|
|
|
|
// get the tangent magnitude this, again, is the same as the distance
|
|
|
|
// between the two circle centers since our circles have the same radius
|
|
|
|
// between the two circle centers since our circles have the same radius
|
|
|
|
route_csc.tangent.magnitude = ( (route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0) +
|
|
|
|
route_csc.tangent.magnitude =
|
|
|
|
(route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0) ).sqrt();
|
|
|
|
((route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0)
|
|
|
|
|
|
|
|
+ (route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0))
|
|
|
|
|
|
|
|
.sqrt();
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the start circle
|
|
|
|
// get the angle of the start circle
|
|
|
|
route_csc.start.angle = 90.0 - route_csc.tangent.angle;
|
|
|
|
route_csc.start.angle = 90.0 - route_csc.tangent.angle;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.start.angle < 0.0 { route_csc.start.angle += 360.0; }
|
|
|
|
if route_csc.start.angle < 0.0 {
|
|
|
|
if route_csc.start.angle >= 360.0 { route_csc.start.angle -= 360.0; }
|
|
|
|
route_csc.start.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.start.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.start.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// 90° to it's own direction and the magnitude of the circle radius
|
|
|
|
// 90° to it's own direction and the magnitude of the circle radius
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
x: route_csc.start.circle.center.x + route_csc.start.circle.radius * (180.0-route_csc.start.angle).to_radians().cos(),
|
|
|
|
x: route_csc.start.circle.center.x
|
|
|
|
y: route_csc.start.circle.center.y + route_csc.start.circle.radius * (180.0-route_csc.start.angle).to_radians().sin()
|
|
|
|
+ route_csc.start.circle.radius * (180.0 - route_csc.start.angle).to_radians().cos(),
|
|
|
|
|
|
|
|
y: route_csc.start.circle.center.y
|
|
|
|
|
|
|
|
+ route_csc.start.circle.radius * (180.0 - route_csc.start.angle).to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the start circle
|
|
|
|
// get the angle of the start circle
|
|
|
|
@ -100,8 +130,12 @@ pub fn rsr(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
route_csc.end.angle = end.angle - route_csc.start.angle;
|
|
|
|
route_csc.end.angle = end.angle - route_csc.start.angle;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.end.angle < 0.0 { route_csc.end.angle += 360.0; }
|
|
|
|
if route_csc.end.angle < 0.0 {
|
|
|
|
if route_csc.end.angle >= 360.0 { route_csc.end.angle -= 360.0; }
|
|
|
|
route_csc.end.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.end.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.end.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(route_csc)
|
|
|
|
Ok(route_csc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -109,9 +143,28 @@ pub fn rsr(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
/// left straight left route
|
|
|
|
/// left straight left route
|
|
|
|
pub fn lsl(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
pub fn lsl(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
start: CircleRoute { circle: Circle { center: Point {x:-end.magnitude, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
start: CircleRoute {
|
|
|
|
tangent: Vector { origin: Point { x: 0.0, y: 0.0 }, angle: 0.0, magnitude: 0.0},
|
|
|
|
circle: Circle {
|
|
|
|
end: CircleRoute { circle: Circle { center: Point {x: 0.0, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
center: Point {
|
|
|
|
|
|
|
|
x: -end.magnitude,
|
|
|
|
|
|
|
|
y: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
tangent: Vector {
|
|
|
|
|
|
|
|
origin: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
magnitude: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
end: CircleRoute {
|
|
|
|
|
|
|
|
circle: Circle {
|
|
|
|
|
|
|
|
center: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
@ -120,50 +173,71 @@ pub fn lsl(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
// and again we have to use the counter clockwise direction
|
|
|
|
// and again we have to use the counter clockwise direction
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
x: end.origin.x + end.magnitude * (180.0 - end.angle).to_radians().cos(),
|
|
|
|
x: end.origin.x + end.magnitude * (180.0 - end.angle).to_radians().cos(),
|
|
|
|
y: end.origin.y + end.magnitude * (180.0 - end.angle).to_radians().sin()
|
|
|
|
y: end.origin.y + end.magnitude * (180.0 - end.angle).to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent pitch which is the same as the pitch between the two
|
|
|
|
// get the tangent pitch which is the same as the pitch between the two
|
|
|
|
// circle centers since our circles have the same radius
|
|
|
|
// circle centers since our circles have the same radius
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - route_csc.start.circle.center.y) /
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - route_csc.start.circle.center.y)
|
|
|
|
(route_csc.end.circle.center.x - route_csc.start.circle.center.x)).atan().to_degrees();
|
|
|
|
/ (route_csc.end.circle.center.x - route_csc.start.circle.center.x))
|
|
|
|
|
|
|
|
.atan()
|
|
|
|
|
|
|
|
.to_degrees();
|
|
|
|
|
|
|
|
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// start circle center x value
|
|
|
|
// start circle center x value
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x { route_csc.tangent.angle += 180.0; }
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x {
|
|
|
|
|
|
|
|
route_csc.tangent.angle += 180.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle positive
|
|
|
|
// make the angle positive
|
|
|
|
if route_csc.tangent.angle < 0.0 { route_csc.tangent.angle += 360.0; }
|
|
|
|
if route_csc.tangent.angle < 0.0 {
|
|
|
|
|
|
|
|
route_csc.tangent.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent magnitude this, again, is the same as the distance
|
|
|
|
// get the tangent magnitude this, again, is the same as the distance
|
|
|
|
// between the two circle centers since our circles have the same radius
|
|
|
|
// between the two circle centers since our circles have the same radius
|
|
|
|
route_csc.tangent.magnitude = ( (route_csc.end.circle.center.x - route_csc.start.circle.center.x).abs().powf(2.0) +
|
|
|
|
route_csc.tangent.magnitude = ((route_csc.end.circle.center.x
|
|
|
|
(route_csc.end.circle.center.y - route_csc.start.circle.center.y).abs().powf(2.0) ).sqrt();
|
|
|
|
- route_csc.start.circle.center.x)
|
|
|
|
|
|
|
|
.abs()
|
|
|
|
|
|
|
|
.powf(2.0)
|
|
|
|
|
|
|
|
+ (route_csc.end.circle.center.y - route_csc.start.circle.center.y)
|
|
|
|
|
|
|
|
.abs()
|
|
|
|
|
|
|
|
.powf(2.0))
|
|
|
|
|
|
|
|
.sqrt();
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the start circle
|
|
|
|
// get the angle of the start circle
|
|
|
|
route_csc.start.angle = route_csc.tangent.angle - 90.0;
|
|
|
|
route_csc.start.angle = route_csc.tangent.angle - 90.0;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.start.angle < 0.0 { route_csc.start.angle += 360.0; }
|
|
|
|
if route_csc.start.angle < 0.0 {
|
|
|
|
if route_csc.start.angle >= 360.0 { route_csc.start.angle -= 360.0; }
|
|
|
|
route_csc.start.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.start.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.start.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// 90° to it's own direction and the magnitude of the circle radius
|
|
|
|
// 90° to it's own direction and the magnitude of the circle radius
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
x: route_csc.start.circle.center.x + route_csc.start.circle.radius * route_csc.start.angle.to_radians().cos(),
|
|
|
|
x: route_csc.start.circle.center.x
|
|
|
|
y: route_csc.start.circle.center.y + route_csc.start.circle.radius * route_csc.start.angle.to_radians().sin()
|
|
|
|
+ route_csc.start.circle.radius * route_csc.start.angle.to_radians().cos(),
|
|
|
|
|
|
|
|
y: route_csc.start.circle.center.y
|
|
|
|
|
|
|
|
+ route_csc.start.circle.radius * route_csc.start.angle.to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the start circle
|
|
|
|
// get the angle of the start circle
|
|
|
|
// the angle where we start from the tangent equals the one we finish
|
|
|
|
// the angle where we start from the tangent equals the one we finish
|
|
|
|
// so we can use that in here
|
|
|
|
// so we can use that in here
|
|
|
|
route_csc.end.angle = end.angle - route_csc.start.angle;
|
|
|
|
route_csc.end.angle = end.angle - route_csc.start.angle;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.end.angle < 0.0 { route_csc.end.angle += 360.0; }
|
|
|
|
if route_csc.end.angle < 0.0 {
|
|
|
|
if route_csc.end.angle >= 360.0 { route_csc.end.angle -= 360.0; }
|
|
|
|
route_csc.end.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.end.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.end.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(route_csc)
|
|
|
|
Ok(route_csc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -171,9 +245,28 @@ pub fn lsl(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
/// right straight left route
|
|
|
|
/// right straight left route
|
|
|
|
pub fn rsl(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
pub fn rsl(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
start: CircleRoute { circle: Circle { center: Point {x: end.magnitude, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
start: CircleRoute {
|
|
|
|
tangent: Vector { origin: Point { x: 0.0, y: 0.0 }, angle: 0.0, magnitude: 0.0},
|
|
|
|
circle: Circle {
|
|
|
|
end: CircleRoute { circle: Circle { center: Point {x: 0.0, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
center: Point {
|
|
|
|
|
|
|
|
x: end.magnitude,
|
|
|
|
|
|
|
|
y: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
tangent: Vector {
|
|
|
|
|
|
|
|
origin: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
magnitude: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
end: CircleRoute {
|
|
|
|
|
|
|
|
circle: Circle {
|
|
|
|
|
|
|
|
center: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
@ -182,54 +275,77 @@ pub fn rsl(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
// and again we have to use the counter clockwise direction
|
|
|
|
// and again we have to use the counter clockwise direction
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
x: end.origin.x + end.magnitude * (180.0 - end.angle).to_radians().cos(),
|
|
|
|
x: end.origin.x + end.magnitude * (180.0 - end.angle).to_radians().cos(),
|
|
|
|
y: end.origin.y + end.magnitude * (180.0 - end.angle).to_radians().sin()
|
|
|
|
y: end.origin.y + end.magnitude * (180.0 - end.angle).to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// check if inside tangent can even be constructed
|
|
|
|
// check if inside tangent can even be constructed
|
|
|
|
if ((route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0) + (route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0)).sqrt()
|
|
|
|
if ((route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0)
|
|
|
|
< 2.0 * end.magnitude {
|
|
|
|
+ (route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0))
|
|
|
|
|
|
|
|
.sqrt()
|
|
|
|
|
|
|
|
< 2.0 * end.magnitude
|
|
|
|
|
|
|
|
{
|
|
|
|
return Err(());
|
|
|
|
return Err(());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent length via some simple trigonometry
|
|
|
|
// get the tangent length via some simple trigonometry
|
|
|
|
route_csc.tangent.magnitude = (( route_csc.end.circle.center.x - route_csc.start.circle.center.x ).powf(2.0) +
|
|
|
|
route_csc.tangent.magnitude =
|
|
|
|
( route_csc.end.circle.center.y - route_csc.start.circle.center.y ).powf(2.0) - ( 2.0 * end.magnitude ).powf(2.0)).sqrt();
|
|
|
|
((route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0)
|
|
|
|
|
|
|
|
+ (route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0)
|
|
|
|
|
|
|
|
- (2.0 * end.magnitude).powf(2.0))
|
|
|
|
|
|
|
|
.sqrt();
|
|
|
|
|
|
|
|
|
|
|
|
// tangent middle is the same as the middle of the straight from the center of the start
|
|
|
|
// tangent middle is the same as the middle of the straight from the center of the start
|
|
|
|
let tangent_middle = Point {
|
|
|
|
let tangent_middle = Point {
|
|
|
|
x: (route_csc.end.circle.center.x + route_csc.start.circle.center.x) / 2.0,
|
|
|
|
x: (route_csc.end.circle.center.x + route_csc.start.circle.center.x) / 2.0,
|
|
|
|
y: (route_csc.end.circle.center.y + route_csc.start.circle.center.y) / 2.0
|
|
|
|
y: (route_csc.end.circle.center.y + route_csc.start.circle.center.y) / 2.0,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent angle
|
|
|
|
// get the tangent angle
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - tangent_middle.y)/(route_csc.end.circle.center.x - tangent_middle.x)).atan().to_degrees() -
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - tangent_middle.y)
|
|
|
|
( 2.0 * end.magnitude / route_csc.tangent.magnitude).atan().to_degrees();
|
|
|
|
/ (route_csc.end.circle.center.x - tangent_middle.x))
|
|
|
|
|
|
|
|
.atan()
|
|
|
|
|
|
|
|
.to_degrees()
|
|
|
|
|
|
|
|
- (2.0 * end.magnitude / route_csc.tangent.magnitude)
|
|
|
|
|
|
|
|
.atan()
|
|
|
|
|
|
|
|
.to_degrees();
|
|
|
|
|
|
|
|
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// start circle center x value
|
|
|
|
// start circle center x value
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x { route_csc.tangent.angle += 180.0; }
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x {
|
|
|
|
|
|
|
|
route_csc.tangent.angle += 180.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the start circle
|
|
|
|
// get the angle of the start circle
|
|
|
|
route_csc.start.angle = 90.0 - route_csc.tangent.angle;
|
|
|
|
route_csc.start.angle = 90.0 - route_csc.tangent.angle;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.start.angle < 0.0 { route_csc.start.angle += 360.0; }
|
|
|
|
if route_csc.start.angle < 0.0 {
|
|
|
|
if route_csc.start.angle >= 360.0 { route_csc.start.angle -= 360.0; }
|
|
|
|
route_csc.start.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.start.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.start.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// along its right angle vector
|
|
|
|
// along its right angle vector
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
x: route_csc.start.circle.center.x + route_csc.start.circle.radius * (180.0-route_csc.start.angle).to_radians().cos(),
|
|
|
|
x: route_csc.start.circle.center.x
|
|
|
|
y: route_csc.start.circle.center.y + route_csc.start.circle.radius * (180.0-route_csc.start.angle).to_radians().sin()
|
|
|
|
+ route_csc.start.circle.radius * (180.0 - route_csc.start.angle).to_radians().cos(),
|
|
|
|
|
|
|
|
y: route_csc.start.circle.center.y
|
|
|
|
|
|
|
|
+ route_csc.start.circle.radius * (180.0 - route_csc.start.angle).to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the end circle
|
|
|
|
// get the angle of the end circle
|
|
|
|
route_csc.end.angle = (90.0 - end.angle) - route_csc.tangent.angle;
|
|
|
|
route_csc.end.angle = (90.0 - end.angle) - route_csc.tangent.angle;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.end.angle < 0.0 { route_csc.end.angle += 360.0; }
|
|
|
|
if route_csc.end.angle < 0.0 {
|
|
|
|
if route_csc.end.angle >= 360.0 { route_csc.end.angle -= 360.0; }
|
|
|
|
route_csc.end.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.end.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.end.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(route_csc)
|
|
|
|
Ok(route_csc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -237,9 +353,28 @@ pub fn rsl(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
/// left straight right route
|
|
|
|
/// left straight right route
|
|
|
|
pub fn lsr(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
pub fn lsr(end: Vector) -> Result<RouteCSC, ()> {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
let mut route_csc = RouteCSC {
|
|
|
|
start: CircleRoute { circle: Circle { center: Point {x: -end.magnitude, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
start: CircleRoute {
|
|
|
|
tangent: Vector { origin: Point { x: 0.0, y: 0.0 }, angle: 0.0, magnitude: 0.0},
|
|
|
|
circle: Circle {
|
|
|
|
end: CircleRoute { circle: Circle { center: Point {x: 0.0, y: 0.0}, radius: end.magnitude}, angle: 0.0 },
|
|
|
|
center: Point {
|
|
|
|
|
|
|
|
x: -end.magnitude,
|
|
|
|
|
|
|
|
y: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
tangent: Vector {
|
|
|
|
|
|
|
|
origin: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
magnitude: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
end: CircleRoute {
|
|
|
|
|
|
|
|
circle: Circle {
|
|
|
|
|
|
|
|
center: Point { x: 0.0, y: 0.0 },
|
|
|
|
|
|
|
|
radius: end.magnitude,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
angle: 0.0,
|
|
|
|
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
// get the center point by adding the end vector to the end point
|
|
|
|
@ -248,55 +383,77 @@ pub fn lsr(end: Vector) -> Result <RouteCSC, ()> {
|
|
|
|
// the angle has to be counter clockwise though (thats why 360 - end.angle)
|
|
|
|
// the angle has to be counter clockwise though (thats why 360 - end.angle)
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
route_csc.end.circle.center = Point {
|
|
|
|
x: end.origin.x + end.magnitude * (360.0 - end.angle).to_radians().cos(),
|
|
|
|
x: end.origin.x + end.magnitude * (360.0 - end.angle).to_radians().cos(),
|
|
|
|
y: end.origin.y + end.magnitude * (360.0 - end.angle).to_radians().sin()
|
|
|
|
y: end.origin.y + end.magnitude * (360.0 - end.angle).to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// check if inside tangent can even be constructed
|
|
|
|
// check if inside tangent can even be constructed
|
|
|
|
if ((route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0) + (route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0)).sqrt()
|
|
|
|
if ((route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0)
|
|
|
|
< 2.0 * end.magnitude {
|
|
|
|
+ (route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0))
|
|
|
|
|
|
|
|
.sqrt()
|
|
|
|
|
|
|
|
< 2.0 * end.magnitude
|
|
|
|
|
|
|
|
{
|
|
|
|
return Err(());
|
|
|
|
return Err(());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent length via some simple trigonometry
|
|
|
|
// get the tangent length via some simple trigonometry
|
|
|
|
route_csc.tangent.magnitude = (( route_csc.end.circle.center.x - route_csc.start.circle.center.x ).powf(2.0) +
|
|
|
|
route_csc.tangent.magnitude =
|
|
|
|
( route_csc.end.circle.center.y - route_csc.start.circle.center.y ).powf(2.0) - ( 2.0 * end.magnitude ).powf(2.0)).sqrt();
|
|
|
|
((route_csc.end.circle.center.x - route_csc.start.circle.center.x).powf(2.0)
|
|
|
|
|
|
|
|
+ (route_csc.end.circle.center.y - route_csc.start.circle.center.y).powf(2.0)
|
|
|
|
|
|
|
|
- (2.0 * end.magnitude).powf(2.0))
|
|
|
|
|
|
|
|
.sqrt();
|
|
|
|
|
|
|
|
|
|
|
|
// tangent middle is the same as the middle of the straight from the center of the start
|
|
|
|
// tangent middle is the same as the middle of the straight from the center of the start
|
|
|
|
let tangent_middle = Point {
|
|
|
|
let tangent_middle = Point {
|
|
|
|
x: (route_csc.end.circle.center.x + route_csc.start.circle.center.x) / 2.0,
|
|
|
|
x: (route_csc.end.circle.center.x + route_csc.start.circle.center.x) / 2.0,
|
|
|
|
y: (route_csc.end.circle.center.y + route_csc.start.circle.center.y) / 2.0
|
|
|
|
y: (route_csc.end.circle.center.y + route_csc.start.circle.center.y) / 2.0,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent angle
|
|
|
|
// get the tangent angle
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - tangent_middle.y)/(route_csc.end.circle.center.x - tangent_middle.x)).atan().to_degrees() +
|
|
|
|
route_csc.tangent.angle = ((route_csc.end.circle.center.y - tangent_middle.y)
|
|
|
|
( 2.0 * end.magnitude / route_csc.tangent.magnitude).atan().to_degrees();
|
|
|
|
/ (route_csc.end.circle.center.x - tangent_middle.x))
|
|
|
|
|
|
|
|
.atan()
|
|
|
|
|
|
|
|
.to_degrees()
|
|
|
|
|
|
|
|
+ (2.0 * end.magnitude / route_csc.tangent.magnitude)
|
|
|
|
|
|
|
|
.atan()
|
|
|
|
|
|
|
|
.to_degrees();
|
|
|
|
|
|
|
|
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// if the end circle center x value is smaller than the
|
|
|
|
// start circle center x value
|
|
|
|
// start circle center x value
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
// the angle would be 180° rotated so to prevent that:
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x { route_csc.tangent.angle += 180.0; }
|
|
|
|
if route_csc.end.circle.center.x < route_csc.start.circle.center.x {
|
|
|
|
|
|
|
|
route_csc.tangent.angle += 180.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the start circle
|
|
|
|
// get the angle of the start circle
|
|
|
|
route_csc.start.angle = route_csc.tangent.angle - 90.0;
|
|
|
|
route_csc.start.angle = route_csc.tangent.angle - 90.0;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.start.angle < 0.0 { route_csc.start.angle += 360.0; }
|
|
|
|
if route_csc.start.angle < 0.0 {
|
|
|
|
if route_csc.start.angle >= 360.0 { route_csc.start.angle -= 360.0; }
|
|
|
|
route_csc.start.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.start.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.start.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// get the tangent origin by moving the vector from the start circle center
|
|
|
|
// 90° to it's own direction and the magnitude of the circle radius
|
|
|
|
// 90° to it's own direction and the magnitude of the circle radius
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
route_csc.tangent.origin = Point {
|
|
|
|
x: route_csc.start.circle.center.x + route_csc.start.circle.radius * route_csc.start.angle.to_radians().cos(),
|
|
|
|
x: route_csc.start.circle.center.x
|
|
|
|
y: route_csc.start.circle.center.y + route_csc.start.circle.radius * route_csc.start.angle.to_radians().sin()
|
|
|
|
+ route_csc.start.circle.radius * route_csc.start.angle.to_radians().cos(),
|
|
|
|
|
|
|
|
y: route_csc.start.circle.center.y
|
|
|
|
|
|
|
|
+ route_csc.start.circle.radius * route_csc.start.angle.to_radians().sin(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// get the angle of the end circle
|
|
|
|
// get the angle of the end circle
|
|
|
|
route_csc.end.angle = (90.0 - end.angle) - route_csc.tangent.angle;
|
|
|
|
route_csc.end.angle = (90.0 - end.angle) - route_csc.tangent.angle;
|
|
|
|
|
|
|
|
|
|
|
|
// make the angle pretty
|
|
|
|
// make the angle pretty
|
|
|
|
if route_csc.end.angle < 0.0 { route_csc.end.angle += 360.0; }
|
|
|
|
if route_csc.end.angle < 0.0 {
|
|
|
|
if route_csc.end.angle >= 360.0 {route_csc.end.angle -= 360.0; }
|
|
|
|
route_csc.end.angle += 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if route_csc.end.angle >= 360.0 {
|
|
|
|
|
|
|
|
route_csc.end.angle -= 360.0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(route_csc)
|
|
|
|
Ok(route_csc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|