In matter.js I am constructing a random polygon body (actually a randomly shaped car with wheels). The set of vertices of this body are accessible using the vertices property. I want to select a random vertex and attach a constraint to it.
In my code bodyB is the car, and bodyB is a wheel.
var axelB = Constraint.create({
bodyB: body,
bodyA: wheelB,
pointB: { x: 0, y: 0 },
// pointB: { x: -50, y: -20 },
stiffness: 0,
length: 0,
});
Here pointB is an offset in reference to the centroid of the polygon.
All I want to do is select a random vertex and place the wheel on it but I do not know how to translate between the centroid's coordinates and a point on the vertex I've chosen.
In the attached image the wheel is drawn at the centroid, I want to put it on one of the body edges instead.
Related
How do I check if the user geolocation is in the square area defined by 2 geopoints that define the square diagonal?
Like in the next photo.
How do I make a function that returns true if the user geolocation is in the white square defined by those 2 points?
You can use bool overlaps(Rect other) method..
Create a Rect from user location with 1 radius
Rect userRect = Rect.fromCircle(center:Offset(UserPositionDx,UserPositionDy),radius:1);
Create a Rect from PointA and PointB ( Please check whether these points are defined as Offset(double dx,double dy) if not convert it to Offset )
Rect areaSquare = Rect.fromPoints(PointA,PointB);
Create a bool variable and set it
false at the begining
bool isUserInArea=false;
Check if user position (as Rect with 1 radius) is overlaped by area
isUserInArea=areaSquare.overlaps(userRect);
I want to get a result like this while the white circle is being actually a punch:
However, I'm getting the following result when I follow the boolean operation example:
// this works okay
var via = outer.exclude(hole)
project.activeLayer.addChild(via)
// this works weird
var drilledY = y.exclude(hole)
project.activeLayer.addChild(drilledY)
Here the only problem seems to be creating the hole inside the Path. How can I create a hole in the path?
I don't think you can get the result you want using Path.Line.
Punching through implies that you want to remove some internal area, which an open Path such as Path.Line lacks.
So what you can do is the following:
Replace those thick Lines with Path.Rectangles.
unite the 2 rectangles, to get your cross, so you have one Path to operate on.
Use subtract instead of exclude to "punch through".
Here's an example:
var x = new paper.Path.Rectangle({
from: [100, 100],
to: [120, 200],
fillColor: 'red',
strokeWidth: 1
});
var y = x.clone().rotate(90).set({ fillColor: 'blue' })
// Unite x/y to get a single path.
var cross = y.unite(x)
// Remove x,y we no longer need them, we got the cross.
x.remove()
y.remove()
var hole = new paper.Path.Circle({
center:[110, 150],
radius: 6,
strokeColor: 'red',
fillColor: 'red'
})
// Subtract (instead of exclude), to "punch through".
var drilled = cross.subtract(hole)
// Remove hole/cross, we no longer need them.
hole.remove()
cross.remove()
console.log(drilled)
and here's a Sketch.
If you don't want to unite your shapes, you can still loop through them
and subtract the hole from them, just remember to use closed Paths.
I'm working in JavaFX for a class, and I'm trying to apply a gradient to a sphere, but (obviously), I can't figure out how to do it. I'm stuck because I know that a sphere is an object, and so it needs to have a material, but (as far as colors go), a PhongMaterial only takes one color, and so it won't take a gradient because a gradient is a range of colors. So basically what I'm trying to is the following:
Sphere sphere = new Sphere(50);
RadialGradient rg = new RadialGradient(0, 0, 0, 0, 5, true, CycleMethod.REPEAT, /*arbitrary/irrelevant color Stop objects*/));
PhongMaterial pm = new PhongMaterial();
pm.setDiffuseMap(pm);
sphere.setMaterial(asdf);
Now obviously this code doesn't work, but I guess it's the idea/flow of what I'm trying to do.
You are right about one thing, PhongMaterial takes a Color as diffuse color, and that doesn't allow a Gradient. For that, it should accept Paint, but that is not the case.
So we have to look for different alternatives.
DiffuseMap
If you check PhongMaterial, you can set the diffuse map with an image. That means that you can use an existing image with some gradient and apply it to the sphere.
Something like this:
Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image("http://westciv.com/images/wdblogs/radialgradients/simpleclorstops.png"));
sphere.setMaterial(material);
will produce the following result:
Dynamic DiffuseMap
Obviously, this has the disadvantage of depending on a static image. What if you want to modify that dynamically?
You can do that, if you generate your radial gradient, render it on a secondary scene and take a snapshot of it. This snapshot returns a WritableImage that you can use directly as diffuse map.
Something like this:
Scene aux = new Scene(new StackPane(), 100, 100,
new RadialGradient(0, 0, 0.5, 0.5, 1, true, CycleMethod.REPEAT,
new Stop(0, Color.GREEN), new Stop(0.4, Color.YELLOW),
new Stop(0.6, Color.BLUE), new Stop(0.7, Color.RED)));
WritableImage snapshot = aux.snapshot(null);
Sphere sphere = new Sphere(100);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(snapshot);
sphere.setMaterial(material);
You will have now:
Density Map
There is still another option to use a mathematical function to generate a density map, and the colors will be given by a mapping to that function.
For that you can't use the built-in Sphere, but you have to either create your own TriangleMesh and play with the texture coordinates, or you can simply use FXyz, an open source JavaFX 3D library with a number of different primitives and texture options.
For this case, you can get the library from Maven Central (org.fxyz3d:fxyz3d:0.3.0), use a SegmentedSphereMesh control, and then select the texture mode `Vertices3D:
SegmentedSphereMesh sphere = new SegmentedSphereMesh(100);
sphere.setTextureModeVertices3D(1530, p -> p.z);
Note the function in this case is just based on the z coordinate, but obviously you can modify that as needed.
Check the library (there is a sampler), to explore other options.
I don't have any code to share at this point, but I'm trying to figure out how to solve my issue.. I was hoping some of you might have some advice.
I'm building an app where I get the user's lat/long from geolocation and if they are in an predetermined area with a radius they can post data to the server, but not if they aren't in an area that I specified is allowed.. Here is an image for example:
So in this example, the user could post if they are in the radius of one of the circles but not if they aren't.
I would also have to fetch the data based off of which circle they are in..
What I'm wondering is, how would I specify where these radius' exist and does this scale easily? If I needed to add 10-30 new locations would that be easy to do?
You have the user location from the device and as you have the circles; you have the circle centre with their radius. At time of posting, you check the distance from the user location to the circle centre and enumerate thought the circle locations. if the distance is within the radius, they can post if not, not.
var radius = 100 //example
let canPostLocations = [
CLLocation1,
CLLocation2
]
func isInRange() -> Bool {
for canPost in canPostLocations {
let locationDistance = location.distance(from: canPost)
if (locationDistance < radius) {
return true
}
}
return false
}
use as:
var mayPost = false
var userLocation: CLLocation! = nil
if userLocation != nil {
mayPost = InRange(location: userLocation).isInRange()
}
Running/walking distance display.
User enters a location and a distance.
I can overlay a circle with a radius of the distance the user entered, with the user's location as the center point.
I can set four cardinal points (N, S, E, W) around the point of origin at the distance the user set and draw the routes to those points, such that point B is 100KM from point A, but the mapped route is, say, 145km along the road.
Is it possible to display a route along the road exactly 100km?
Edited to update progress.
Finally solved this and thought I'd share.
so, the user supplies a location and a distance; we'll say 100Km.
The code finds cardinal points 100Km N, S, E, W of the point of origin, then solves routes to each point. If solving for the route is successful, the result contains an array of points from the point of origin to the destination.
directionsService.route({
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function(result) {
renderDirections(result);
});
//don't use the google api DirectionsRender() to draw the route.
//instead - result holds an array of lat/long points that make up the entire route. Lets say it's latlong[123]
//iterate through that array, getting a distance from point A to latlong[0], A to latlong[1], etc...
//when that distance is >= user supplied distance, STOP, and draw a polyline from point A through the latlong points in the array latlong[78]
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
if(myroute)
{
//create a LatLon from the Starting point
var objGeo = new LatLon(Geo.parseDMS(myroute.overview_path[0].Qa), Geo.parseDMS(myroute.overview_path[0].Ra));
//call get distance from the starting point to each other point in the array
//each subsequent point should be a longer distance
var arrPointsToDraw =[];
for(var i = 1; i<=myroute.overview_path.length-1;i++)
{
try
{
var objGeo2 = new LatLon(Geo.parseDMS(myroute.overview_path[i].Qa), Geo.parseDMS(myroute.overview_path[i].Ra));
}
catch(err)
{
alert(err.description);
}
//here, total = kilometers
total = objGeo.distanceTo(objGeo2,3);
//add coordinates to our array of points that we are going to draw
arrPointsToDraw.push(new google.maps.LatLng(objGeo2._lat, objGeo2._lon));
if(parseInt(total) > parseInt(distance.value))
{
arrPointsToDraw.pop();//remove the last element of the array
break;
}
}
//at this point, arrPointsToDraw[] contains the lat/long points that are closest to our distance
//without going over
lines[lines.length] = new google.maps.Polyline({
path: arrPointsToDraw,
strokeColor: '#1589FF',
strokeOpacity: 1.0,
strokeWeight: 3
});
lines[lines.length-1].setMap(map);
}//end if(myRoute)
}
This code makes use of two fantastic collections of functions found here