2013-05-28 7 views
30

Wie kann ich erkennen, wenn der Benutzer in die rote Blase klickt?Erkennen, ob der Benutzer innerhalb eines Kreises klickt

Es sollte nicht wie ein quadratisches Feld sein. Die Maus wirklich innerhalb des Kreises sein muss:

img

Hier ist der Code:

<canvas id="canvas" width="1000" height="500"></canvas> 
<script> 
var canvas = document.getElementById("canvas") 
var ctx = canvas.getContext("2d") 

var w = canvas.width 
var h = canvas.height 

var bubble = { 
    x: w/2, 
    y: h/2, 
    r: 30, 
} 

window.onmousedown = function(e) { 
    x = e.pageX - canvas.getBoundingClientRect().left 
    y = e.pageY - canvas.getBoundingClientRect().top 

    if (MOUSE IS INSIDE BUBBLE) { 
     alert("HELLO!") 
    } 
} 

ctx.beginPath() 
ctx.fillStyle = "red" 
ctx.arc(bubble.x, bubble.y, bubble.r, 0, Math.PI*2, false) 
ctx.fill() 
ctx.closePath() 
</script> 
+1

Wenn Sie die Position des Cursors und die Position und Größe des Kreises kennen (und es ist wirklich ein Kreis, nicht ein Auslassungszeichen), es ist nur eine einfache geometrische Berechnung, um festzustellen, ob der Punkt (der Cursor) innerhalb des Kreises liegt oder nicht. http://stackoverflow.com/questions/481144/equation-for-testing-if-a-point-is-inside-a-circle – qJake

+0

Hören von Sinus und Cosinus ...? – CBroe

+1

@CBroe Trig wird in diesem Fall nicht benötigt und wäre auch nicht nützlich. –

Antwort

45

Ein Kreis ist die geometrische Lage aller Punkte, deren Abstand von einem zentralen Punkt gleich einige Nummer "R".

Sie möchten die Punkte finden, deren Abstand kleiner oder gleich dem "R", unserem Radius, ist.

Die Abstandsgleichung im 2d euklidischen Raum ist d(p1,p2) = root((p1.x-p2.x)^2 + (p1.y-p2.y)^2).

Überprüfen Sie, ob der Abstand zwischen Ihrer und der Mitte des Kreises kleiner als der Radius ist.

Nehmen wir an, ich habe einen Kreis mit Radius r und Mitte bei Position (x0,y0) und einen Punkt (x1,y1) und ich möchte überprüfen, ob dieser Punkt im Kreis ist oder nicht.

Ich würde müssen überprüfen, ob d((x0,y0),(x1,y1)) < r was übersetzt:

Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)) < r 

In JavaScript.

Jetzt wissen Sie, all diese Werte (x0,y0) sein bubble.x und bubble.y und (x1,y1)x und y zu sein.

+0

p1 ist der Mittelpunkt Ihres Kreises (den Sie bereits mit Breite/2 und Höhe/2 berechnet haben). p2 ist die aktuelle Mausposition, die Sie mit dem Kreis vergleichen. –

3

berechnen einfach die distance zwischen dem Mauszeiger und der Mitte des Kreises, dann entscheiden, ob es im Inneren ist:

var dx = x - bubble.x, 
dy = y - bubble.y, 
dist = Math.sqrt(dx * dx + dy * dy); 

if (dist < bubble.r) { 
    alert('hello'); 
} 

Demo

Wie mentioned in den Kommentaren, Math.sqrt() zu beseitigen können Sie:

var distsq = dx * dx + dy * dy, 
rsq = bubble.r * bubble.r; 

if (distsq < rsq) { 
    alert('HELLO'); 
} 
+5

Sie können sogar die "teure" Math.sqrt durch das Testen wie folgt ausschneiden: dx * dx + dy * dy markE

+0

@markE ausgezeichneter Punkt :) danke! –

2

Eine Alternative (nicht immer nützlich, was bedeutet, dass es nur eine Alternative gibt) y Arbeit für den letzten Weg (re) definiert, aber ich bringe es nach oben als Option):

x = e.pageX - canvas.getBoundingClientRect().left 
y = e.pageY - canvas.getBoundingClientRect().top 

if (ctx.isPointInPath(x, y)) { 
    alert("HELLO!") 
} 

Pfad kann btw. sei jede Form.

Für weitere Informationen:
http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath

+0

+1 für eine Antwort, die einen beliebigen Pfad umfasst. Denken Sie daran zu erwähnen, dass der zu testende Pfad unmittelbar vor dem Treffertest mit isPointInPath definiert (oder neu definiert) werden muss. – markE

26

Um zu testen, ob ein Punkt innerhalb eines Kreises ist, mögen Sie, wenn der Abstand bestimmen, zwischen dem gegebenen Punkt und dem Mittelpunkt des Kreises ist kleine als der Radius Der Kreis.

Anstatt die Punkt-Entfernung-Formel zu verwenden, bei der eine (langsame) Quadratwurzel verwendet wird, können Sie die nicht quadratisch verwurzelte (oder noch quadratische) Entfernung zwischen den Punkten vergleichen.Wenn diese Entfernung kleiner ist als die Radius im Quadrat, dann bist du dabei!

// x,y is the point to test 
// cx, cy is circle center, and radius is circle radius 
function pointInCircle(x, y, cx, cy, radius) { 
    var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy); 
    return distancesquared <= radius * radius; 
} 

(nicht Ihr Code verwenden, weil ich die Funktion allgemein für Zuschauer halten wollen, die später auf diese Frage kommen)

Diese etwas komplizierter ist, zu verstehen, aber es ist auch schneller, und wenn Sie beabsichtigen, Wenn Sie einen Punkt-in-Kreis in einer Zeichnungs/Animations/Objekt-Bewegungsschleife prüfen, sollten Sie dies auf dem schnellsten Weg tun.

Verwandte JS perf-Test:

http://jsperf.com/no-square-root

+1

Vielen Dank für die Erstellung von lesbarem und wiederverwendbarem Code. Nur ein Hinweis auf den Leistungstest, in modernen Browsern scheint es, dass die Verwendung der Quadratwurzel immer etwas schneller ist. – pedalpete

Verwandte Themen