<script src="/lernen/jquery/3.7.1/jquery.min.js"></script>
Hier kann man das Ganze interaktiv ausprobieren. Wenn der Abstrahlwinkel flach ist steigt die Reichweite. Ist der Abstrahlwinkel steil, so verkürzt sich die Reichweite.
<script>
// Setup Canvas:
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
// Functions:
function Vector(x, y) {
this.x = x || 0;
this.y = y || 0;
}
Vector.prototype = {
ort: function() {
return new Vector(this.y,-this.x);
},
add: function(v) {
return new Vector(this.x + v.x, this.y + v.y);
},
rotate : function(angle) {
return new Vector(
Math.cos(angle)*this.x - Math.sin(angle)*this.y,
Math.sin(angle)*this.x + Math.cos(angle)*this.y
);
},
sp: function(v) {
return this.x * v.x + this.y * v.y;
},
factor: function(f) {
return new Vector(f*this.x, f*this.y);
},
length : function () {
return Math.sqrt(this.x*this.x+this.y*this.y);
},
norm : function() {
return new Vector(this.x/this.length(),this.y/this.length());
},
negate : function() {
return new Vector(-1*this.x, -1*this.y);
},
angle: function(a) {
return Math.acos(this.sp(a) / (this.length() * a.length()));
},
clone: function() {
return new Vector(this.x, this.y);
},
};
function intersectionCircle(s, r, radius) {
// I'm already proud of the derivation :-P So my Abi wasn't in vain after all
sp = s.sp(r);
lambda1 = -1*(sp) + Math.sqrt(Math.pow(sp,2)-s.sp(s)+Math.pow(radius,2));
return s.add(r.factor(lambda1));
}
function intersectionCircle2(s, r, radius) {
// I'm already proud of the derivation :-P So my Abi wasn't in vain after all
sp = s.sp(r);
lambda2 = -1*(sp) - Math.sqrt(Math.pow(sp,2)-s.sp(s)+Math.pow(radius,2));
return s.add(r.factor(lambda2));
}
function drawLine(ctx, start, end, strokecolor, lineWidth) {
ctx.beginPath();
ctx.moveTo(start.x, start.y);
ctx.lineTo(end.x, end.y);
ctx.lineWidth = lineWidth;
if(strokecolor != "") {
ctx.strokeStyle = strokecolor;
}
ctx.stroke();
}
function drawCircle(ctx, origin, radius, fillcolor, strokecolor, lineWidth){
ctx.beginPath();
ctx.arc(origin.x, origin.y, radius, 0, 2 * Math.PI, false);
if(fillcolor != "") {
ctx.fillStyle = fillcolor;
ctx.fill();
}
ctx.lineWidth = lineWidth;
if(strokecolor != "") {
ctx.strokeStyle = strokecolor;
}
ctx.stroke();
}
function drawArc(ctx, origin, radius, angle, fillcolor, strokecolor, lineWidth){
ctx.beginPath();
ctx.arc(origin.x, origin.y, radius, Math.PI/4, Math.PI/4+angle*Math.PI/180, false);
if(fillcolor != "") {
ctx.fillStyle = fillcolor;
ctx.fill();
}
ctx.lineWidth = lineWidth;
if(strokecolor != "") {
ctx.strokeStyle = strokecolor;
}
ctx.stroke();
}
function drawScene(ctx, angle) {
// Clean Canvas:
ctx.canvas.width = 600;
ctx.canvas.height = 200;
// Set origin to center:
ctx.translate(canvas.width * 0.5, canvas.height * 1);
// Flip Canvas to normal:
ctx.scale(1, -1);
// Origin:
M = new Vector(0,0);
// Set Radius
var radiusEarth = 100;
var radiusAtmosphere = 180;
// Sender Point:
S = new Vector(-radiusEarth/Math.sqrt(2),radiusEarth/Math.sqrt(2));
// Draw Antenna:
antennaTop = S.factor(1.2);
antennaMiddle = S.factor(1.1);
antennaRadius = antennaTop.length();
drawLine(ctx,S, antennaTop, "#000000", 1);
ast1 = S.rotate(0.75*Math.PI).norm();
ast2 = S.rotate(0.25*Math.PI).norm();
end1 = intersectionCircle2(antennaMiddle, ast1, antennaRadius);
end2 = intersectionCircle(antennaMiddle, ast2, antennaRadius);
drawLine(ctx, antennaMiddle, end1, "#000000", 1);
drawLine(ctx, antennaMiddle, end2, "#000000", 1);
// Create Vector nomalized orthogonal to the Senderpoint:
Sorth = S.ort().norm();
// Draw Earth and Atmosphere:
drawCircle(ctx, M, radiusEarth, "#49ace9", "", 1);
drawCircle(ctx, M, radiusAtmosphere, "", "#ffbab5", 25);
// Rotate this normalized vector with the beaming angle:
beam1 = Sorth.rotate(angle*Math.PI/180);
// Create the point where the beam intersects with the Atmosphere
cp1 = intersectionCircle(S, beam1, radiusAtmosphere);
// Draw beam 1:
drawLine(ctx, S, cp1, "#fe756c", 3);
// Calculate the angle between cp1neg and beam 1 neg:
cbAngle = cp1.angle(beam1);
// Calculate cp1neg:
cp1neg = cp1.negate();
// Rotate cp1neg by the cbAngle and normalize it:
beam2 = cp1neg.rotate(cbAngle).norm();
// Create the point where the beam intersects with the Earth Circle
cp2 = intersectionCircle2(cp1, beam2, radiusEarth);
// Draw beam 2:
drawLine(ctx, cp1, cp2, "#fe756c", 3);
// Create the point where ground reference intersects with Atmosphere
gp1 = intersectionCircle(S, Sorth, radiusAtmosphere);
drawLine(ctx, S, gp1, "#999999", 1);
gp2 = intersectionCircle2(S, Sorth, radiusAtmosphere);
drawLine(ctx, S, gp2, "#999999", 1);
// Draw Angle
drawArc(ctx, S, 40, angle, "", "#999999", 1);
}
drawScene(ctx, 0);
$("#beamAngle").on("change", function() {
console.log("DRAW");
angle = $(this).val();
drawScene(ctx, angle);
$('#beamAngleField').html(angle);
});
</script>