Discrete approach with Python
A possible approch that avoids solving the equation would consist in interating through all possible points in the 3D space, check whether or not in each one of them the equation is verified, and if it is create a vertex there.
As in the 3D space there are infinite points, we must discretize it and limits the boundaries of the investigation domain. For the sake of semplicity, I choose to consider, for example, only integer numbers from -100 to +100 for each axis. Here's the code for such iteration:
for x in range(-100,100):
for y in range(-100,100):
for z in range(-100,100):
Then, for each vector we'll calculate the left member of the equation and check if it's equal to the right member of the equation previusly defined. As we discretized the domain, it's best to give to the result a bit of "tollerance" in verifying the equation (that's why I'm using the "+/-toll" trick upon the right member verification).
function=2*x**2+y**2-5*z**2+z-7*x #function here
if((function<(goal+toll))and(function>(goal-toll))):
bm.verts.new([x,y,z])
Here's a possible code with all the lines needed to create an object in the scene:
import bpy
import bmesh
mesh = bpy.data.meshes.new("mesh")
obj = bpy.data.objects.new("Function", mesh)
scene = bpy.context.scene
scene.objects.link(obj)
scene.objects.active = obj
obj.select = True
mesh = bpy.context.object.data
bm = bmesh.new()
goal=16 #right member of the equation
toll=5 #threshold
for x in range(-100,100):
for y in range(-100,100):
for z in range(-100,100):
function=2*x**2+y**2-5*z**2+z-7*x #function here
if((function<(goal+toll))and(function>(goal-toll))):
bm.verts.new([x,y,z])
bm.to_mesh(mesh)
bm.free()
Examples of usage:
function=2*x**2+y**2-5*z**2+z-7*x
Note: as you can see, it takes a while to iterate through all the 8 000 000 positions...
This script only provides some of the vertices due to the approximation, but, with a proper resolution, you can obtain a good representation of the surface.
The meshing of the vertices into a surface needs it's own approach. This "brute force plotting" I'm proposing does not go well with the "on the fly" definitions of faces. The set of point is not structured in any way. You'll need something to mesh the pointcloud.
Here's another version of the code where you can better control the domain size and resolution using floats to inspect the region closer to the origin in high definition:
import bpy
import bmesh
max=7
min=-7
prec=10 #precision of the calc (1=1 units, 10 = 0.1 units, 100 = 0.01 units...)
tol=0.5 #tollerance
def f(x, y, z): return 2*x**2+y**2-5*z**2+z-7*x -16 #the function = 0
mesh = bpy.data.meshes.new("mesh")
obj = bpy.data.objects.new("XYZ Function", mesh)
scene = bpy.context.scene
scene.objects.link(obj)
scene.objects.active = obj
obj.select = True
mesh = bpy.context.object.data
bm = bmesh.new()
for x in [float(j)/prec for j in range(min*prec, max*prec+1,1)]:
for y in [float(j)/prec for j in range(min*prec, max*prec+1,1)]:
for z in [float(j)/prec for j in range(min*prec, max*prec+1,1)]:
if(abs(f(x,y,z))<tol):
bm.verts.new([x,y,z])
bm.to_mesh(mesh)
bm.free()
Here's a possible result:

You can for example export points to Meshlab and take advantage of the built in tools. Here's an example using the previusly obtained set of points.
