PhotoMatch by intersecting ray tracing
-
Hi folks,
I originally posted this in the SketchUp Discussions, but at Gaieus' suggestion, I'm copying it over here in the Ruby thread-group.
I've been thinking about a problem for a while -- if I had a generic solution there are several placed I could apply it.
The issue is using PhotoMatch with photos that just do not have enough straight lines or maybe no lines that can be counted on to be vertical or level. Like making a SketchUp model of the Mystery House at Knott's Berry Farm, or The Santa Cruz Mystery Spot -- or worse, trying to form terrain from photographs.
I assume it would require there to be lots and lots of common points in the photographs that you can match up. But just points, probably not many lines, horizontal or not. Very much the kind of thing that the standard PhotoMatch perspective tools are really bad at.
What I keep coming back to is being able to pick the same point in two or 3 photos and construct lines through the photo image to the camera. The actual 3D point has to lie on that ray from the camera center through the point in the PhotoMatch image, out to infinity. Two or three photos let you find the intersection of the rays.
To play with how the geometry of this works out, to start getting a handle on what the rules of this game have to be, it would be nice to be able to place a PhotoMatch image into a model as a photo texture on a surface, oriented perpendicular to the line to camera for that PM scene. And then, from the viewpoint of that scene, pick a point in the image and run a ruby script that would construct the ray from the camera through that image point.
So has anyone created a script like that, to generate a ray from the camera through a point chosen on a surface or simply through the cursor position?
If no one has done it yet, I'd be willing to hack at it, if someone could toss out hints of what objects and methods would have to be used.
Thanks for any suggestions,
August -
@unknownuser said:
So has anyone created a script like that, to generate a ray from the camera through a point chosen on a surface or simply through the cursor position?
Hi,
I did something similar for my view-based face reverser. Look at the "raycast" method which is quite simple to use.
Regards, -
@didier bur said:
I did something similar for my view-based face reverser. ...
Thanks for the tip, Didier,
I finally found that plugin attached at http://www.sketchucation.com/forums/scf/viewtopic.php?f=153&t=5333.
Searching the Depot for "view reverse" does not turn it up. However, on the Depot, page 1 of the search results says there are 27 results and page 2 says there are 19, back and forth, consistently. Weird.
August
-
@didier bur said:
... Look at the "raycast" method which is quite simple to use.
@august said:
I finally found that plugin attached at http://www.sketchucation.com/forums/scf/viewtopic.php?f=153&t=5333.
The attached file there includes a very nice PDF describing the operation. From the PDF, I would think that the script used a method that I might indeed adapt. Unfortunately, in the vbfr.rb file, the Ruby Script itself is encoded.
Can you suggest where I might find an un-encoded version or advise me on how to decode that one?
Thanks,
August -
@didier bur said:
... Look at the "raycast" method which is quite simple to use.
@august said:
I finally found that plugin attached at http://www.sketchucation.com/forums/scf/viewtopic.php?f=153&t=5333.
Hi Didier,
It seems I found the wrong "view-based face reverser". I succeeded in getting the script unpacked and printed to the Ruby Console by changing "eval" to "print" and running "load "vbfr.rb"" on the console. I then copy/pasted it into a text file.
Unfortunately, I could find no "raycast" method in that script. I found "pickray" and "raytest" used, but no definition for either. I found "raytest" in the Google SketchUp Ruby API Method Index, but no "pickray".
Could you please point me to where that "raycast" method might be found?
Or is "raycast" a misremembering of the name "raytest"? If so, what/where is "pickray"?
Thanks,
August -
Hi folks,
I'm trying to understand "pickray" from Didier's use of it, since I cannot find it documented.
Didier's script uses raytest and pickray like this:
p = view.screen_coords(v.position) px=p[0] py=p[1] #test each pixel around each vertex ### # # ### #test the vertex itself first ray = view.pickray [px,p.y] rt = m.raytest([ray[0], ray[1]]) return true if rt and rt[1][0] == self ray = view.pickray [px-1,p.y+1] rt = m.raytest([ray[0], ray[1]]) return true if rt and rt[1][0] == self ...
From that, it looks like view.pickray might be exacly what I am
looking for, but I can't find it defined or documented anywhere.Also, as Ruby Newbie, I am confused at the asymmetry of the arguments
to pickray.Didier defines px=p[0] and py=p[1] yet for pickray he supplies
[px,p.y] and increments and decrements both of them similarly to test
all the adjacent pixels, but he maintains that distinction between px
and p.y notationally.Are these as truly synonymous as they appear, or is there a reason
for doing one value one way and the other value another way?Thanks,
August -
@chris fullmer said:
... So it looks like thy are interchangeable since he's defined the x and y into px and py. px = p.y and py = p.y I think. ...
Thanks Chris,
That's the way I read it, but being a Newbie, my first impulse is to blame my lack of understanding rather than to assume that a master like Didier used an accurate but inconsistent syntax nine times in a row. (Obviously cut and pasted, but it's still there nine times).
My debugging my own code depends a lot on being very anal about spaces and forms and indents and punctuation, adding lots of extra spaces to make as much as possible line up to show the parallel structures etc. so the errors will stand out. Obviously Didier does not need the same kinds of crutches because he just reads what it means.
Thanks for the reassurance that I did read it right in the first place.
Unless there is a trick here that we're both missing.
August
P.S. And thanks for the link to a pickray reference.
-
@chris fullmer said:
The sample code for pickray uses vertex.position[0] and vertex.position[1] as the x, y screen position of the vertex.
But the doc for the position method for a vertex says that it returns a Point3D object. The doc for the Point3D class says "The Point3d class allows you to work with a point in 3d space. The point is basically just a series of values representing x, y and z coordinates. The values are specified as [x,y,z]. For example [100,200,300]."
So the only way that makes sense to me, for the doc to actually be completely accurate, is for the x and y of a Point3D object to be the x and y of the current view, rather than being SU's red and green axes. But if that is the case, why doesn't the Point3D doc SAY that? But if the x,y,z of a Point3D is not the view, with z being distance from the camera plane, then what part of the doc is wrong?
Am I interpreting it wrong, or is the doc just skipping over a very basic concept that is essential to understanding the object being described?
Anybody?
Thanks,
August -
Well, here's some info on pickray:
And to me it looks like p might contain [x, y, z] info. So saying p.x would return x. But he's already defined the px = p[0], which is also the x value. And the same for the y value. So it looks like thy are interchangeable since he's defined the x and y into px and py. px = p.x and py = p.y I think. (Now Jim or Rick or Todd will step in and explain all my theory away )
Chris
-
Well I can't explain what it means. This stuff is over my head for now. I've not had to get into ray's and such just yet (though I've got a project in the pipeline that might require it).
But I can explain the Docs. They are horrible! Todd just recently pointed out that there are 3 separate places to find documentation. Each is more incomplete than the previous. There have been numerous times that I've been looking for something and couldn't find it. Only to realize that it was omitted from the doc I was looking at. This seems to be a rather common complaint.
There seems to be quite a few of us who are trying to figure this ruby out right now. I can say that I'm having a blast when I'm not frustrated
Chris
-
From a Point3d standpoint, it can be treated as a 3 element array.
p[0] and p.x are always x
p[1] and p.y are always y
p[2] and p.z are always zDoubt can arise when you choose to use x or y or z as standalone variables.
I'm surprised noone here as asked what a ray was yet!
-
@unknownuser said:
p[0] and p.x are always x
p[1] and p.y are always y
p[2] and p.z are always z ...Thanks Todd,
That confirms the way I read the code, so I'm not going to worry about there being any subtle tricks embedded in using px and p.y in the same tuple. The py variable is defined and never used. Gee.
[If I were editing this for publication, I'd probably suggest leaving out the definitions of px and py as only saving a single character later in the p.x and p.y constructions while the definitions take up two full lines of example space. If I were debugging it for speed and px and py were being used thousands of times, I'd probably go with the variable rather than thousands of p.x and p.y method lookups. Case in point on the difference between an Engineering and an API Doc mindset.]
HOWEVER, the question remains, is the x,y,z of a Point3D based in screen coordinates or model coordinates? It sure looks from Didier's usage that it's screen-based, but you would think (and you could be wrong) that it would be mentioned in the Point3D doc.
For now, I will assume that a Point3D refers to screen-space, since that's the way Didier uses it and I trust that the script works and I have other evidence of the doc being incomplete on rather basic issues. Since screen-space is the dominant coordinate system for the problem I posed in starting this thread, that's really useful.
Thanks to all,
August -
A Geom::Point3d can be a point in 3D model space, or it can represent a screen coordinate, depending on its use. Google didn't create a Point2d, so, whenever a screen coordinate is needed, just use a Point3d and ignore the z value.
-
Thanks Todd,
@unknownuser said:A Geom::Point3d can be a point in 3D model space, or it can represent a screen coordinate, depending on its use. ...
So it's just a 3-tuple that only has "meaning" by what you put into it and what you use that for?
If I'm converting model coordinates to screen coordinates, I could use a Point3D for both input and output and keep track of them by name, etc., but it would be the same object type on both ends of the conversion?
Thanks,
August -
Yes.
Advertisement