gimymblert
|
|
« on: November 18, 2016, 04:54:21 PM » |
|
I have been working on this problem for a while and I'm having bogus result for reason I don't know Right I'm only trying to get magnitude right, I don't compute the coordinate yet, so the circle is on the origin and the point is on the x axis to simplify. Capital letters define known quantity, lower case denote unknown and derive quantity. Given a circle C or radius R and a point P at distance D, how to find the p0 where the tangent from P to the circle go through? Let's define: l the distance between P and p0 It seems like a simple problem, given than the the tangent point have a perpendicular that goes through the center of C it became a simple Pythagora things where: R² + l² = D² We know R and D but not l so we can turn it into D² - R² = l² We can further: let's break the triangle C,P,P0 into two right angle triangle such as there is point T where the perpendicular to D through P0 intersect D, let's call the segment between T and P0, h. Let's call segment P,T and T,C respectively b and a. such as a+b = d. Since we are axis align on x and centered on origin, the line D is on the axis such as y=0 (therefore a and b are, and h is parallel to y). Given that finding the tangent coordinate is given by (a,h). h, a and b are unknown by can be express through pythagora: h² + b² = l² h² + a² = R² we know l relative to R and D h²+b² = D² - R² we can express D² in term of a and b D = a + b D² = (a+b)² D² = a² + 2ab + b² which lead to: h² + b² = a² + 2ab + b² -R² let's express h² h² = a² + 2ab + b² -R² -b² //b² get cancel h² = a² + 2ab -R² we can express b in term of b = D-a h² = a² + 2a(D-a) -R² h² = a² + 2aD -2a² -R² //a² get cancel h² = 2aD - a² -R² we already know h² + a² = R² we can express R: h² + a² = 2aD -R² R² = 2aD -R² 2R² = 2aD R² = aD we can now express a in term of known term a = R²/D Now we can come back to express h² in term of h² = 2aD - a² -R² h² = 2(R²/D)D - (R²/D)² - R² //R² and D get cancel h² = R² - (R^4/D²) Now we can have express the target coordinate (a,h) in term of know quantity (a,h) = (R²/D , sqr (R² - (R^4/D²) ) ) Result Is there a problem with my reasoning somewhere?
|
|
« Last Edit: November 18, 2016, 05:08:48 PM by gimymblert »
|
Logged
|
|
|
|
valambrian
|
|
« Reply #1 on: November 18, 2016, 07:59:35 PM » |
|
The math looks right. What are the numbers (a, h, D, R) related to the last graph?
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #2 on: November 18, 2016, 09:21:42 PM » |
|
The yellow circle is the target circle C of radius R the red circle is the point P from which I want the tangent The grey circle is supposed to be the tangent point p0 on C with x = a, and y = h The line between both circle center is D For the algorithm defense, it make sure the fake tangent never cross the circle does not help though
|
|
|
Logged
|
|
|
|
|
gimymblert
|
|
« Reply #4 on: November 19, 2016, 07:51:10 AM » |
|
I looked at it but I can't remeber what x and y are and why they are similar in the 2 circle equation. I'm thinking (x1,y1) are the center coordinate, therefore (x,y) must the be origin right? which game us the segment [x,x1] and [x,x2] being the right angled side of the triangle and r the hypothenuse, hence why the equation of a circle is x²+y² = r², but that does not translate if x = y = 0, ,i'm clearly missing something here
|
|
|
Logged
|
|
|
|
Glyph
|
|
« Reply #5 on: November 19, 2016, 08:49:58 AM » |
|
x and y should not be substituted with your center coordinates, they are the variables that you plot the circle with in the usual way by finding all solutions to the equation. The full equation for a circle is (x-h)^2 + (y-k)^2 = r^2, where (h,k) denotes the center of your circle.
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #6 on: November 21, 2016, 01:06:23 PM » |
|
So I tried everything, apparently the equation thingy just gave me something I had already tried formerly but with magnitude replace instead of coordinate, or else I get stuck in equation wolfram alpha don't help either ... I cave in and looked at programming code to copy: http://csharphelper.com/blog/2014/09/determine-where-two-circles-intersect-in-c/STILL DON'T WORK Though bug are different now ...
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #7 on: November 21, 2016, 01:15:09 PM » |
|
If the math is correct, then maybe there is some coding error you're missing? Have you done standard debugging? Maybe step/trace through the code using a simple example that someone else has done by hand. That way you can see where it goes wrong.
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
gimymblert
|
|
« Reply #8 on: November 21, 2016, 01:22:40 PM » |
|
Have been doing that for one week, but the bug I fixed didn't significantly fixed the problem I had mostly a problem of doubling data for no reason, which was due to how circle are computed (they are generated inside a rect in the form of x,y width,height, radius was diameter (height and width) but apparently I didn't have to divide by 2 for some reason ) Graphics3D 1000,600,0,2 SetBuffer BackBuffer()
Const offsetx = -350
Origin offsetx+GraphicsWidth()/2, GraphicsHeight()/2
;planet visibility ;- surface limit (min height or Radius) ;- max height (+radius) ;- max atmosphere (+radius)
radius# = 90 maxheight# = 20 atmosphere# = 40
planetx# = 0 planety# = 0; 100
;distance = 0 ;radius + distance to surface shipx# = 200 shipy# =0; -50
;------------------------------------------- cam = CreateCamera () PositionEntity cam, 0,0,-25
l1 = CreateLight (1) RotateEntity l1, 45,45,0
;center = CreateSphere (3) ;PositionEntity center, 0,0,0 ;ScaleEntity center, 5,5,5 ;EntityColor center, 255,0,0 ;-------------------------------------------
While Not KeyDown(1)
;refresh UpdateWorld 1 RenderWorld 1
shipx = -offsetx+ MouseX()-GraphicsWidth()/2
;axis Color 255,0,0:Line 0,-GraphicsHeight(),0, GraphicsHeight() Color 0,255,0:Line -GraphicsWidth(),0,GraphicsWidth(),0
;cursor guide ;Color 255,255,255:Line 125,-GraphicsHeight(),125, GraphicsHeight() ;Color 255,255,255:Line -GraphicsWidth(),0,GraphicsWidth(),0
;ship position Color 255,0,0: circle (shipx,shipy, 10)
;planet position Color 255,255,0: circle(planetx, planety, radius*2)
;planet/ship distance Color 128,128,128: Line shipx, shipy, planetx, planety
;data psx = planetx - shipx psy = planety - shipy
dist# = magnitude(psx, psy)
r2# = radius^2 d2# = dist^2
a = (r2)/dist h = Sqr(r2 - ((r2*r2)/(dist^2)) )
ix2 = shipx + a * psx /dist iy2 = shipy + a * psy /dist
circle (ix2 ,iy2 ,20)
itx2 = (ix2 - h * psy) /dist ity2 = (iy2 + h * psx) /dist
itx1 = ix2 + h * psy /dist ity1 = iy2 - h * psx /dist
;tangent vis circle (itx2, ity2,20) circle (itx1, ity1,20)
Line shipx, shipy, a,h Line shipx, shipy, a,-h Line planetx, planety, a, -h Line planetx, planety, a, h
;distance circle circle (shipx, shipy, dist*2)
;mid distance circle (tangent intersect?) Color 0,255,255: circle( (planetx+shipx)*.5, (planety+shipy)*.5,magnitude((shipx-planetx), (shipy-planety)))
Text 0,0, a;hg;(planety+shipy)*0.5;ht;magnitude(shipx-planetx, shipy-planety)
VWait:Flip False Wend ClearWorld
;------------------------------------------- Function magnitude#(x#,y#) Return Sqr ((x^2) + (y^2)) End Function
Function normalizeX#(x#,y#) Return x/magnitude(x,y) End Function
Function normalizeY#(x#,y#) Return y/magnitude(x,y) End Function
Function Circle(x#,y#, radius#) Oval x-radius*0.5, y-radius*0.5, radius,radius,0 Plot x,y End Function
Function powerof2step(x) ;which step you are on : int 1 = Return Floor (Log (x)/Log(2) ) ;height of that step, float h = pow(2,i) End Function
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #9 on: November 21, 2016, 01:27:13 PM » |
|
what... what's that language? :S Blitz something?
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
oahda
|
|
« Reply #10 on: November 21, 2016, 01:54:33 PM » |
|
good ol blitzbasic
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #11 on: November 21, 2016, 02:56:41 PM » |
|
so.. uh.. blitzbasic code. Do you have debug tools? Can you write tests? Do you generally know how to debug code that does math?
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
gimymblert
|
|
« Reply #12 on: November 21, 2016, 03:13:09 PM » |
|
I know nothing about writing test though.
We have debug tools we can step line by line and look at all the variables, but I'm using visual confirmation instead, my current theory is the variable "a" is fuck somewhere, it work on axis align, it's also curved so it might be tied to positioning, so I'm back at looking at coordinate computaion (in case if it's x1-x2 instead of x2-x1), that's my current hypothesis (after a nap break)
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #13 on: November 21, 2016, 03:43:47 PM » |
|
I solved the problem by blinding shifting stuff along the intuition above ... now I need to make it worked with, maximum height (the tangent find the intersecting outgoing point), atmosphere, then in 3D >.< (note 3d would work the same for the radius shenanigan, I need to figure out the 3D position, I think it can be inferred from teh 2D model anyway)
|
|
« Last Edit: November 21, 2016, 03:51:19 PM by gimymblert »
|
Logged
|
|
|
|
J-Snake
|
|
« Reply #14 on: November 23, 2016, 04:45:32 PM » |
|
Let me put an end to your misery:
Since (D, R, L) is a right triangle, P_0 is exactly on a circle which is uniquely defined having D as a diagonal. Therefore P_0 is the point of intersection of the two circles:
One-liner in C#:
var P0 = Util.Math.IntersectCircleCircle(new Circle(center of D, D/2), new Circle(C, R));
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #15 on: November 23, 2016, 10:59:53 PM » |
|
It's not c# But thanks I will port it to c# later! blitz is for dirty quick prototype without polluting production code EDIT: I can't find the reference on c#'s doc, do you have a link? edit2: that's not c# that's JAVA! https://joml-ci.github.io/JOML/apidocs/org/joml/Intersectionf.html
|
|
« Last Edit: November 23, 2016, 11:05:33 PM by gimymblert »
|
Logged
|
|
|
|
J-Snake
|
|
« Reply #16 on: November 24, 2016, 03:34:16 PM » |
|
It's in-house C#-code to give you an idea how it can look like. I assume you know how to determine the collision point/s of two circles (if not, get familiar with math concepts first). If you program your library intelligently, you will store the radius as a vector.
|
|
|
Logged
|
|
|
|
gimymblert
|
|
« Reply #17 on: November 24, 2016, 05:32:43 PM » |
|
That's not clever at all because the whole point of this thread is to debug this very problem (which I did, it's equivalent) Also vector is just a representation, it's a pair of coordinate, you still have to operate on the coordinate, that does not change anything how I store them. Anyway the radius is a scalar, it's not a vector, you are supposed to derive the vector from the two radius. ANYWAY Yes it's turned into a function now. That was disappointing I thought you were onto something ...It's like you read nothing
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #18 on: November 25, 2016, 05:35:21 AM » |
|
We have debug tools we can step line by line and look at all the variables, but I'm using visual confirmation instead
I think this may be your main problem. Visual confirmation is great if you quickly want to check is something is obviously wrong. But once you know it's wrong, it's close to useless to keep using visual confirmation, because it doesn't tell you what's wrong. One thing you can do to debug: 1. Create an easy test example 2. Solve it by hand and verify the solution with wolframalpha or something similar 3. Step through the code and check where your hand-calculation differs from your program's calculation One thing you can do to make it easier to debug: 1. Put the algorithm in a function 2. Break out parts of the algorithm to subfuctions (for example intersect(cirlceA, circleB), distance(pointA, pointB), etc.) 3. Test all the functions independently. If you can verify that distance(pointA, pointB) always works correctly, then you know the problem isn't in that piece of code To formalize it you can write tests: 1. Take a function you want to test (intersect, distance, findtangent, etc.) 2. Create example problems and solve them (for example by hand, or wolframalpha, or examples you find online) 3. Write a test program that feeds the function with the problem and checks that it returns correct value Let's say you want to test you function add(a, b), you could to this: if (add(1, 2) != 3) { print("error: add(1, 2), expected 3, got " + add(1, 2)) }
if (add(-1, 2) != 1) { print("error: add(-1, 2), expected 1, got " + add(-1, 2))) }
if (add(-1, -1) != -2) { print("error: add(-1, -1), expected -2, got " + add(-1, -1))) }
So you write a question and an answer by hand and the program then checks if it works. Many languages have libraries that help you do this more automatically, but you can write it by hand like that or write your own helper functions. Then whenever you change something, you can run the program and check if it works now or if something else has stopped working. This isn't always useful, but it can save you lots of effort if you find yourself trying to verify things visually (which takes some time and only works with one thing at a time). haha, wow, J-Snake never ceases to amaze
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
J-Snake
|
|
« Reply #19 on: November 25, 2016, 03:46:02 PM » |
|
because the whole point of this thread is to debug this very problem I assumed the point is to compute P0. Just ignore the part about storing radius as a vector, as it is most likely going to confuse you. It is just a side note related to performance considerations.
|
|
|
Logged
|
|
|
|
|