FromPoint does not intersect it's own IPolyline5 - arcobjects

I have a Polyline and a Point FeatureClass.
I create a point feature on the Point layer for both the FromPoint and the ToPoint of the IPolyline5 similar to below:
IFeature pointFeature1 = pointFeatureClass.CreateFeature ();
pointFeature1.Shape = polyline.FromPoint;
IFeature pointFeature2 = pointFeatureClass.CreateFeature ();
pointFeature2.Shape = polyline.ToPoint;
Later, I then run both the from point and to point geometries through a method like the below to find all the intersecting polyline features from the polyline feature class.
ISpatialFilter filter = new SpatialFilter ();
filter.Geometry = pointGeometry;
filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
IFeatureCursor cursor = lineFeatureClass.FeatureClass.Search (filter, false);
At the very least, the intersect filter should find the polyline off which I got the 2 points. The strange thing is, it works for the FromPoint, but not with the ToPoint.
Both feature classes are using the same Geographic Coordinate System and Projected Coordinate System.
I hope I am doing something stupid, but just can't figure out what.

I got it to work consistently with esriSpatialRelIntersects by just buffering the point by 0.001.

When creating new features from existing features, you should not use the direct reference, but the ShapeCopy. Try to change yout first block to:
pointFeature1.Shape = polyline.FromPoint.ShapeCopy;
pointFeature2.Shape = polyline.ToPoint.ShapeCopy;

instead of
pointFeature1.Shape = polyline.FromPoint;
use
PointFeature1.Shape = ((polyline.FromPoint as IPoint) as IFeature).ShapeCopy;
and for
pointFeature2.Shape = polyline.ToPoint;
use
PointFeature1.Shape = ((polyline.ToPoint as IPoint) as IFeature).ShapeCopy;

Related

How can I use the new raycast in Roblox Studio?

I am trying to learn how to use the Raycast system in Roblox studio, I don't have enough experience in Roblox studio to understand what's going on here, or rather how I am going to change or update this line of code since this is deprecated.
local function castRay ()
local origin = firePoint.Position
local direction = (mouse.Hit.p - firePoint.Position).Unit
direction = direction * gunSettings.range
local ray = Ray.new(origin, direction)
local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
replicatedStorage.Replicate:FireServer(tool, origin)
local visual = Instance.new("Part")
local length = (pos - origin).Magnitude
Specifically on local hit, pos, this is now deprecated as stated in roblox studio, as well as local ray, now I did research that this kind of code can be used instead of the following two that I just mentioned
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
But the following lines such as length requires pos variable, I don't know how I can move forward thanks to this. So there is no error for now, but I am asking cause I want to implement the new raycast system in this function, and I'm kind of stuck on how to do it, Here is the full code of the function:
local function castRay ()
local origin = firePoint.Position
local direction = (mouse.Hit.p - firePoint.Position).Unit
direction = direction * gunSettings.range
local ray = Ray.new(origin, direction)
local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
replicatedStorage.Replicate:FireServer(tool, origin)
local visual = Instance.new("Part")
local length = (pos - origin).Magnitude
visual.Anchored = true
visual.CanCollide = false
visual.Material = Enum.Material.Neon
visual.Color = gunSettings.rayColor
visual.Size = Vector3.new(gunSettings.raySize.X, gunSettings.raySize.Y, length)
visual.CFrame = CFrame.new(origin, pos)*CFrame.new(0,0,-length/2)
visual.Parent = workspace.Effects
debris:AddItem(visual, gunSettings.debrisTime)
return hit, pos, direction, origin
end
If you look at the docs for WorldRoot:Raycast, you'll see a code sample on how to utilize the new raycast function.
The new API just packages the data a little differently. Rather than passing your ignorelist into the raycast function, you pass it into the RaycastParams object. And all of the data you get back is packaged into a RaycastResult object.
So you can adapt your code simply like this :
local function castRay()
local origin = firePoint.Position
local direction = (mouse.Hit.p - firePoint.Position).Unit * gunSettings.range
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = ignoreList
local raycastResult = workspace:Raycast(origin, direction, raycastParams)
local hit = raycastResult.Instance
local pos = raycastResult.Position
The rest of your code should work just as before.

Grouping (without collision), adding and removing multiple bodies and polygons in pymunk?

I'm using code from the pymunk index_video to create a generic function that creates multiple cars which race each other and if they reach the right extreme of the screen, they are removed from Space and re-generated on the left extreme of the screen.
The problem is, that in the example code, each part of the car (chassis, pin joint, motor, wheels) is added to Space separately. I wanted to treat the entire car as a single body whose coordinates I can keep track of by storing the reference of the entire car body in a List and add or delete it to the Space easily.
Also, if the wheels are too close to the chassis, they collide with each other. I presume using a ShapeFilter can help avoid such collisions, but for that I need all parts of the car as a single body.
Please bear with me. I'm completely new to this jargon.
def car(space):
pos = Vec2d(100,200)
wheel_color = 52,219,119
shovel_color = 219,119,52
mass = 100
radius = 25
moment = pymunk.moment_for_circle(mass, 20, radius)
wheel1_b = pymunk.Body(mass, moment)
wheel1_s = pymunk.Circle(wheel1_b, radius)
wheel1_s.friction = 1.5
wheel1_s.color = wheel_color
space.add(wheel1_b, wheel1_s)
mass = 100
radius = 25
moment = pymunk.moment_for_circle(mass, 20, radius)
wheel2_b = pymunk.Body(mass, moment)
wheel2_s = pymunk.Circle(wheel2_b, radius)
wheel2_s.friction = 1.5
wheel2_s.color = wheel_color
space.add(wheel2_b, wheel2_s)
mass = 100
size = (50,30)
moment = pymunk.moment_for_box(mass, size)
chassi_b = pymunk.Body(mass, moment)
chassi_s = pymunk.Poly.create_box(chassi_b, size)
space.add(chassi_b, chassi_s)
vs = [(0,0),(25,45),(0,45)]
shovel_s = pymunk.Poly(chassi_b, vs, transform = pymunk.Transform(tx=85))
shovel_s.friction = 0.5
shovel_s.color = shovel_color
space.add(shovel_s)
wheel1_b.position = pos - (55,0)
wheel2_b.position = pos + (55,0)
chassi_b.position = pos + (0,-25)
space.add(
pymunk.PinJoint(wheel1_b, chassi_b, (0,0), (-25,-15)),
pymunk.PinJoint(wheel1_b, chassi_b, (0,0), (-25, 15)),
pymunk.PinJoint(wheel2_b, chassi_b, (0,0), (25,-15)),
pymunk.PinJoint(wheel2_b, chassi_b, (0,0), (25, 15))
)
speed = 4
space.add(
pymunk.SimpleMotor(wheel1_b, chassi_b, speed),
pymunk.SimpleMotor(wheel2_b, chassi_b, speed)
)
So this question is actually two questions.
A. How to make a "car object" that consists of multiple parts
There is no built in support for this, you have keep track of it yourself.
One way to do it is to create a car class that contains all the parts of the car. Something like this (not complete code, you need to fill in the full car)
class Car():
def __init__(self, pos):
self.wheel_body = pymunk.Body()
self.wheel_shape = pymunk.Circle()
self.chassi_body = pymunk.Body()
self.chassi_shape = pymunk.Poly()
self.motor = pymunk.SimpleMotor(wheel_body, chassi_body, 0)
def add_to_space(self, space)
space.add(self.wheel_body, self.wheel_shape, self.chassi_body, self.chassi_shape, self.motor)
def set_speed(self, speed)
self.motor.rate = speed
def car_position(self)
return self.chassi_body.position
B. How to make parts of the car to not collide with each other
This is quite straight forward, just as you already found the ShapeFilter is the way to go. For each "car", create a ShapeFilter and set a unique non-zero group on it. Then set that ShapeFilter as the filter property on each shape that makes up the car. It doesnt matter if the shapes belong to the same body or not, any shape with a ShapeFilter with a group set will not collide to other shapes with the same group set.

Compare value of property of all instances of class in python

I'm trying to write an object oriented program (as a learning exercise, I know there may be simpler ways to do it) in which beads bounce around a 2D plane bounded by a ring. Each bead is an object defined by a class ball. In setting the initial positions of the balls I need to check that no other ball has already been placed at the same x and y coordinates.
#Class for the beads
class ball:
NumbBalls = 0
#Constructor
def __init__(self,Beads):
self.ball = sphere(pos = vector(0,0,0), radius = radiusBall,color=color.red)
ball.NumbBalls += 1
self.ball.pos = self.createInitialPosition(Beads)
#Assign ball its initial position
def createInitialPosition(self,other):
#CODE to compare self.ball.pos and other.ball.pos which returns a unique position coordinate
#Main program
NumbBeads = 100
Beads = []#Create empty list for all the beads
#create balls in random initial positions
Beads = [ball(Beads) for item in range(NumbBeads)]
I can get this to work if I create two objects bead1 and bead2 and then pass bead1 and bead2 as arguments ie bead2 = ball(bead1) but how do I do this if I am generating a list of beads and want all of them to be compared with self. Hopefully that makes sense.
Perhaps rather than the approach you are currently taking, you should consider something along these lines (of course, with the necessary changes to your class definition/methods):
N = 100
initialPositions = []
while len(initialPositions) <= N:
newPosition = generateRandomPosition()
if newPosition in initialPositions:
pass
else:
initialPositions.append(newPosition)
ballList = [ ball(p) for p in initialPositions ]
In other words, generate a list of initial positions outside of the creation of your objects, and do whatever validation/restriction you need during that creation. Then just create your objects from that list. If N is really large, you might want to consider a dictionary (or a mutable set of some sort) instead of a list for initialPositions, to help speed up the membership testing, but it's still the same concept...

iText - PdfAnnotation.createInk

I am trying to parse annotation data in XFDF and draw it using the iText Library. I want to draw the annotation like the attached image.
Following is my code to test the PdfAnnotation.createInk function, but it is not working after run the code.
I have Google and read the documents, but not much information provided. Any suggestions and advice? Thanks!
// step 1
Document document = new Document(PageSize.A4);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destFile));
// step 3
document.open();
PdfContentByte pcb = new PdfContentByte(writer);
pcb.setColorStroke(BaseColor.RED);
Rectangle rect = new Rectangle(52.92f, 397.56f, 173.36f, 530.67f);
float[][] inkList = {{61.736111f,530.669250f},{61.295139f,525.820984f},{61.295139f,518.768860f},
{61.295139f,505.986969f},{61.295139f,490.560547f},{61.295139f,470.726562f},{59.972221f,452.214844f},
{57.767361f,434.143890f},{56.003471f,418.276703f},{53.357639f,404.172516f},{51.593750f,391.390625f},
{50.711807f,382.134766f},{49.829861f,376.845703f}
};
//float inkList[][] =
PdfAnnotation an = PdfAnnotation.createInk(writer, rect, "", inkList);
an.setPage(1);
an.setColor(BaseColor.RED);
an.setFlags(PdfAnnotation.FLAGS_PRINT);
writer.addAnnotation(an);
//Step 5
document.close();
The output PDF seemingly does not contain an annotation because the defined annotation is a mere collection of isolated points.
The float[][] parameter of PdfAnnotation.createInk corresponds to the InkList entry of the Ink annotation dictionary:
InkList array (Required) An array of n arrays, each representing a stroked path. Each
array shall be a series of alternating horizontal and vertical coordinates in
default user space, specifying points along the path. When drawn, the
points shall be connected by straight lines or curves in an
implementation-dependent way.
Thus, in case of the OPs array
float[][] inkList = {{61.736111f,530.669250f},{61.295139f,525.820984f},{61.295139f,518.768860f},
{61.295139f,505.986969f},{61.295139f,490.560547f},{61.295139f,470.726562f},{59.972221f,452.214844f},
{57.767361f,434.143890f},{56.003471f,418.276703f},{53.357639f,404.172516f},{51.593750f,391.390625f},
{50.711807f,382.134766f},{49.829861f,376.845703f}
};
we have a collection of 13 paths each of which contain only a single point. So, nothing is drawn.
If we combine all the points in a single path, though,
float[][] inkList = {{61.736111f,530.669250f,61.295139f,525.820984f,61.295139f,518.768860f,
61.295139f,505.986969f,61.295139f,490.560547f,61.295139f,470.726562f,59.972221f,452.214844f,
57.767361f,434.143890f,56.003471f,418.276703f,53.357639f,404.172516f,51.593750f,391.390625f,
50.711807f,382.134766f,49.829861f,376.845703f}
};
the result is this:
which looks like the left line of the "H" in the screenshot in the question.

how to remove a box2d Fixture

I have a square barrier that has edges defined at run time based on where the user puts the position and rotation of my barrier.
b2BodyDef barrierBodyDef;
barrierBodyDef.type = b2_staticBody;
barrierBodyDef.position.Set(curBarrier
.position.x/PTM_RATIO, curBarrier.position.y/PTM_RATIO);
barrierBodyDef.userData = curBarrier;
b2Body *barrierBody;
barrierBody = _world->CreateBody(&barrierBodyDef);
b2EdgeShape barrierEdge;
b2FixtureDef barrierShapeDef;
barrierShapeDef.shape = &barrierEdge;
barrierShapeDef.friction = 1.0f;
barrierEdge.Set(b2Vec2((x1)/PTM_RATIO, (y1)/PTM_RATIO),
b2Vec2((x2)/PTM_RATIO, (y2)/PTM_RATIO));
barrierBody->CreateFixture(&barrierShapeDef);
barrierEdge.Set(b2Vec2((x2)/PTM_RATIO, (y2)/PTM_RATIO),
b2Vec2((x3)/PTM_RATIO, (y3)/PTM_RATIO));
barrierBody->CreateFixture(&barrierShapeDef);
barrierEdge.Set(b2Vec2((x3)/PTM_RATIO, (y3)/PTM_RATIO),
b2Vec2((x4)/PTM_RATIO, (y4)/PTM_RATIO));
barrierBody->CreateFixture(&barrierShapeDef);
barrierEdge.Set(b2Vec2((x4)/PTM_RATIO, (y4)/PTM_RATIO),
b2Vec2((x1)/PTM_RATIO, (y1)/PTM_RATIO));
barrierBody->CreateFixture(&barrierShapeDef);
I now want to delete these edges, so that the user can re-position the barrier.
How do I go about removing the edges between point x1,y1, -> x4,y4, so that they are immune to collisions.
I am a bit new to Box2D.
Keep the fixture when creating it (local var here for example, you should use an ivar):
b2Fixture* barrierFixture = barrierBody->CreateFixture(&barrierShapeDef);
And later destroy the fixture:
barrierBody->DestroyFixture(barrierFixture);
barrierFixture = nil;
You can also use the body's GetFixtureList() to iterate over fixtures.
What you can not do is to add or remove shapes from a fixture, or modify the shape's vertices. To remove a point from a body's shape, you'll have to destroy the fixture and replace it with a new one.
It is not necessary to recreate the entire body, in fact that can be problematic since you'll probably want to preserve the body's current state (not just position but also linear and angular velocities and perhaps other things too).